此问题与this one有关。鉴于此代码:
char *p = new char[200];
delete[] p;
如果在删除p之前设置p[100] = '\0'
会发生什么?
我有一些代码,当我尝试删除一个非空终止的char数组时,我遇到了一个调试错误,这是关于删除未分配的堆内存。它似乎从数组的界限中删除了内存。
答案 0 :(得分:40)
代码:
char *p = new char[200];
p[100] = '\0';
delete[] p;
是完全有效的C ++。 delete不知道或不关心以null结尾的字符串,因此您的错误必须有其他原因。
答案 1 :(得分:8)
没有什么特别的事情会发生。您可以在分配的内存中间的某个位置写入(与启动相隔100个字节,在分配的内存结束之前的99个字节)。
然后你将释放分配的内存。编译器将完全按照我们的预期处理它。由此分配的内存与空终止字符串完全无关。你可以将你想要的一切都粘在那个记忆中。它是一些“原始”存储空间,你甚至可以在该内存中创建一些任意的C ++对象(placement new)。
您的错误在其他地方。例如,一个常见错误是这一个,其中构造函数被调用一次,但析构函数被调用两次,双重删除:
struct A { P *p; A() { p = new P; } ~A() { delete p; } };
A getA() { return A(); } int main() { A a = getA(); }
现在,发生的情况是默认构造函数被调用一次,并且创建的对象被复制零次或多次。但是为每个创建的副本运行析构函数。因此,您将多次调用指针上的析构函数,从而导致此类奇怪的错误。修复 的正确方法是使用智能指针,如shared_ptr
。作为练习,您也可以通过编写适当的复制构造函数来复制对象并在复制构造函数中分配内存,以便复制和相应的原始对象保持不同的指针。
答案 2 :(得分:6)
我认为你将一个普通的旧char数组与一个代表C风格字符串的char数组混淆。 C ++ delete运算符不关心C样式字符串数组。所有它将看到的是一系列字符。这与删除int数组完全没什么不同。
null终止符的存在与否仅与将char*
视为C样式字符串的函数相关。
答案 3 :(得分:3)
没关系。 delete []应该用于删除动态分配的数组而不管其内容。
答案 4 :(得分:1)
据我所知,这应该可以正常工作。您分配了一块内存,操作系统应该跟踪它,并在被询问时能够解除分配。根据你所分配的缓冲区中的值,这应该无关紧要。
在字符数组中间粘贴NULL肯定会干扰strcmp
,strlen
等C字符串函数,但这完全是另一回事。
答案 5 :(得分:0)
正如其他人所说,您发布的代码完全有效,不会造成任何麻烦。
错误可能是由更改p
之间某处的值引起的。