cstring和指针:试图删除字符数组时堆损坏
CStrings and pointers: Heap corruption when trying to delete a character array
我已经用尽自己的谷歌这个,但我没有能够找到一个明确的答案或帮助自己理解什么是错的。作为家庭作业的一部分,我试图动态分配内存的字符数组(即。一个CString)并分配一个char指针变量指向它,然后在我结束程序之前删除分配的内存。我只是把我的头绕在指针上,所以我怀疑我对幕后发生的事情的一些理解是不正确的,我最终使用Visual Studio 2010给我堆损坏断点。
下面是我想做的事情的简化版本(我的注释表示我认为我正在做的事情):
char *chPtr = new char[10]; // Create a char pointer type variable, and point it at the memory allocated for a char array of length 10
chPtr = "September"; // Assign 9 characters (+1 null terminator character) to the char array
cout << chPtr; // Prints "September", then finds the null terminator and stops printing
delete [] chPtr; // THIS is what causes my heap corruption -> But I don't know why. Shouldn't this delete the array of memory that chPtr is pointing at?
- 我也尝试过使用
delete chPtr
,具有相同的堆损坏结果。 - 我已经尝试手动分配null终止符到数组
chPtr[9] = ' ';
的末尾,但这也会导致堆损坏。为什么?当我做cout << chPtr[7];
等事情时,我可以从数组内访问单个字符,而不会出现任何问题……
真正令人困惑的是,这工作没有错误:
char *chPtr = new char[10]; // As above, create a char pointer type and point it at the memory allocated for a char array of length 10
delete chPtr; // This doesn't give any error!
通过赋值来初始化数组似乎在某种程度上破坏了我的工作。
有人能帮我一下吗?chPtr = "September";
改变chPtr
指向的位置。它现在指向静态字符数组"September",而不是指向分配了10个char
s的数组的位置。然后您试图删除它,但失败了。
作为测试,您可以这样做:
char* p = nullptr;
std::cout << static_cast<void*>(p) << "n";
p = new char[10];
std::cout << static_cast<void*>(p) << "n";
p = "September";
std::cout << static_cast<void*>(p) << "n";
可能的输出是:
00000000
0068C988
00D18B34
您可以看到p
所指向的地址在每次赋值时都在变化。在自由存储(0068C988
)上分配的块在第三次赋值时丢失。
如果您想分配字符,请执行
std::strcpy(chPtr, "September");
这伴随着内存管理、数组和指针的所有警告。你真正想做的是:
std::string s = "September";
std::cout << s;
这就是你的问题的根源:
char *chPtr = new char[10]; // Create a char pointer type variable, and point it at the memory allocated for a char array of length 10
chPtr = "September";
首先在chPtr
上分配一个堆内存,然后通过赋值为"september"的非堆char数组分配一个非堆内存(数据段内存)。
你尝试删除非堆内存,然后你得到你得到的错误。
使用strcpy(chPtr,"September")
或者更好:丢掉C,使用std::string
你正试图删除一块内存,你的"九月"所在的地方,它肯定不是分配在堆,如果你需要初始化预分配的缓冲区使用strcpy(..)函数
chPtr = "September"
没有给chPtr
所指向的内存赋值,而是将chPtr
赋值给其他存放"September"的内存。你不能删除这个内存
赋值chPtr = "September";
并不像你想象的那样。它将静态字符数组"September"
的地址赋值给变量chPtr
。当您尝试在它上调用operator delete[]
时,事情出错了:您试图删除静态分配的字符数组。
如果希望复制字符,则必须使用类似std::strcpy的字符串复制函数。
当然,在c++中使用C风格字符串的正确方法是不使用C风格字符串。使用标准的c++ std::basic_string模板之一
- 指向指向字符数组的指针数组的指针
- 比较字符数组
- 如何使用Crypto++并为RSA返回可打印的字节/字符数组
- 使用无符号字符数组有效存储内存
- 按字符值访问int数组
- 错误:字符数组的初始值设定项太多
- 对字符数组中的元素执行逐位操作
- C++,在int数组中输入字符串或字符会输出0,而不是ascii或error
- C++ 无法在字符数组中使用 for 循环打印字母模式
- 如何在 C++ 中从文件中读取字符数组(带有一些空格)
- 移动二维数组中的字符
- C++ 传递二维字符数组
- 无法在 C++ 中输入字符数组
- C++ 带结构的数组字符
- 数组字符包含量超出预期
- 读取文件并添加到数组字符
- 如何在Qt中更改或替换数组字符
- 为什么编译器不在参数中传递数组字符 *arr[] 的大小?
- 井字棋数组字符错误
- 分割数组字符