CStrings 和指针:尝试删除字符数组时堆损坏
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
,但堆损坏结果相同。
- 我已经尝试手动将空终止符分配给数组的末尾
chPtr[9] = '[=13=]';
,但这也会导致堆损坏。为什么?当我做 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!
似乎通过赋值来初始化数组对我来说有点破坏。
有人可以帮我吗?
您正在尝试删除 "September" 所在的内存块,并且它肯定没有分配到堆中,如果您需要初始化预分配缓冲区,请使用 strcpy(..) 函数。
这是您问题的根源:
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
上分配堆内存,然后通过为非堆 char 数组分配 [=22 的值来分配非堆内存(数据段内存,如果准确的话) =] 就可以了。
您尝试删除非堆内存,然后出现错误。
使用 strcpy(chPtr,"September")
甚至更好:去掉 C 并使用 std::string
.
作业 chPtr = "September";
与您认为的不同。它将静态字符数组 "September"
的 地址 分配给变量 chPtr
。当您尝试对其调用 operator delete[]
时,出现了错误:您正在尝试删除静态分配的字符数组。
如果你想复制个字符,你将不得不使用像std::strcpy.
这样的字符串复制函数
当然,在C++中使用C风格字符串的正确方法是不使用C风格字符串。使用标准 C++ std::basic_string 模板之一。
chPtr = "September";
更改 chPtr
指向的位置。它不再指向分配 10 char
的数组的任何位置,而是指向静态字符数组 "September"。然后您尝试删除它,但失败了。
作为测试,您可以试试这个:
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;
chPtr = "September"
不会将任何内容分配给 chPtr
指向的内存,而是将 chPtr
分配给指向确实包含 "September" 的其他内存。你不能删除这段记忆。
我用谷歌搜索这个已经筋疲力尽,但我一直无法找到明确的答案或帮助自己理解出了什么问题。作为家庭作业的一部分,我试图为字符数组(即 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
,但堆损坏结果相同。 - 我已经尝试手动将空终止符分配给数组的末尾
chPtr[9] = '[=13=]';
,但这也会导致堆损坏。为什么?当我做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!
似乎通过赋值来初始化数组对我来说有点破坏。
有人可以帮我吗?
您正在尝试删除 "September" 所在的内存块,并且它肯定没有分配到堆中,如果您需要初始化预分配缓冲区,请使用 strcpy(..) 函数。
这是您问题的根源:
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
上分配堆内存,然后通过为非堆 char 数组分配 [=22 的值来分配非堆内存(数据段内存,如果准确的话) =] 就可以了。
您尝试删除非堆内存,然后出现错误。
使用 strcpy(chPtr,"September")
甚至更好:去掉 C 并使用 std::string
.
作业 chPtr = "September";
与您认为的不同。它将静态字符数组 "September"
的 地址 分配给变量 chPtr
。当您尝试对其调用 operator delete[]
时,出现了错误:您正在尝试删除静态分配的字符数组。
如果你想复制个字符,你将不得不使用像std::strcpy.
这样的字符串复制函数当然,在C++中使用C风格字符串的正确方法是不使用C风格字符串。使用标准 C++ std::basic_string 模板之一。
chPtr = "September";
更改 chPtr
指向的位置。它不再指向分配 10 char
的数组的任何位置,而是指向静态字符数组 "September"。然后您尝试删除它,但失败了。
作为测试,您可以试试这个:
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;
chPtr = "September"
不会将任何内容分配给 chPtr
指向的内存,而是将 chPtr
分配给指向确实包含 "September" 的其他内存。你不能删除这段记忆。