正在使用overriden new[]运算符创建字符串数组
Creating string array with overriden new[] operator
和我的朋友一起,我们用overriden new和new[]运算符制作了一个程序。当我尝试用以下代码创建字符串数组时,我发现:
string* Test1 = new string[10];
函数返回无效指针(通常它的值向前移动8位,我正在将程序编译到x64平台)。我们的新[]功能如下:
void* operator new[] (size_t e)
{
void* Test2 = operator new(e);
return Test2;
}
在返回之前使用调试器运行程序时,指针Test2
的值为0x0000000009dfaa90,但Test1
的值变为0x0000000009 dfaa98。
这种情况只发生在字符串类型中。我试过对"int[10]"、"string*[10]"和我的一个类的对象做同样的操作,但问题只发生在处理字符串时,还有代码:
string* Test1 = new string;
工作非常好。
有人能解释一下为什么会发生这种情况,以及如何使其正确工作吗?
PS:我们正在使用Visual Studio 2012专业版
编辑:我刚刚测试了它的非覆盖new[]
,它在创建字符串表时也以同样的方式工作(返回的指针不是函数尝试return
的指针),所以这似乎不是问题。有人能解释一下为什么指针的值只对字符串数组发生变化,以及若并没有任何其他指令可以改变它,指针的值是如何变化的吗?
答案是new/delete
和new[]/delete[]
不同。这可能不会让你感到惊讶,但另一个令人惊讶的消息(双关语并非有意)是new
运算符和operator new
不同。
以下是测试该问题的示例代码(您可以将tested_type
的typedef'd更改为):
#include <iostream>
#include <vector>
#include <string>
typedef std::string tested_type;
void* Test2;
size_t allocated_mem_size;
void* operator new[] (size_t e)
{
void* retaddr = operator new(e);
Test2 = retaddr;
allocated_mem_size = e;
return retaddr;
}
int _tmain(int argc, _TCHAR* argv[])
{
void* Test1 = new tested_type[10];
std::cout << "sizeof(tested_type)*10 is " << sizeof(tested_type)*10 << "n"
<< "Test1 is " << Test1 << "n"
<< "Test2 is " << Test2 << "n"
<< "operator new[] was called with e == " << allocated_mem_size << "n"
<< "What's in the missing bytes? " << *(size_t*)Test2 << "n";
}
我机器上的输出是:
sizeof(tested_type)*10 is 280
Test1 is 0085D64C
Test2 is 0085D648
operator new[] was called with e == 284
What's in the missing bytes? 10
(注意-我有一个32位编译器)
如果我们将tested_type
更改为int,则我们有:
sizeof(tested_type)*10 is 40
Test1 is 0070D648
Test2 is 0070D648
operator new[] was called with e == 40
What's in the missing bytes? 3452816845
现在,如果我们将tested_type
更改为std::vector<int>
,我们就有
sizeof(tested_type)*10 is 160
Test1 is 004AD64C
Test2 is 004AD648
operator new[] was called with e == 164
What's in the missing bytes? 10
现在我们在这里看到一个模式:添加的额外字节等于分配的元素数量。此外,添加字节的唯一时间是当类型不是平凡的时候。。。
就是这样!
调整地址的原因是new[]
想要存储元素的数量。在某些情况下,我们需要存储元素的数量,而在其他情况下则不需要,这是因为delete[]
调用析构函数,而delete[]
(而不是delete
,它只调用单个元素的析构函数)必须知道它必须销毁多少元素。对于像int
这样的基本类型,不需要调用析构函数,因此new[]
不存储析构函数的数量。
(另外,我推荐std::vector
-它只是起作用)
- 如何使用新运算符跟踪在循环中创建的 QLabel
- 如何创建运算符重载?
- 为什么在C++中使用关系运算符创建的模板函数不能对字符串正常工作?
- 如何在C++中使用 new 运算符创建对动态创建的数组的引用?
- 使用新运算符C++创建多维数组的简单方法
- 为字典cpp创建[]=运算符
- 创建变量之间的运算符排列
- 如何从模板类重载创建的指针对象上的运算符?
- 为什么map使用运算符[]创建新条目
- 赋值运算符创建指针,无法删除
- 通过数组和"new"运算符创建的对象,但如何传递参数?
- 从初始化构造函数和赋值运算符创建的对象有什么区别
- 正在使用overriden new[]运算符创建字符串数组
- 使用模板运算符创建二维关联阵列
- 尝试使用重载运算符创建新的事件处理程序>>迷失了自己试图找出所需的语法
- 使用重载'*'运算符创建多个副本
- 使用基类的运算符>>创建派生类
- 如何使用运算符[]创建模拟类
- new 运算符 - 创建对象指针数组 C++
- 读取使用运算符创建的矩阵