C++ cstring和指针:尝试删除字符数组时堆损坏

C++ cstring和指针:尝试删除字符数组时堆损坏,c++,arrays,pointers,c-strings,C++,Arrays,Pointers,C Strings,我在谷歌上搜索这篇文章已经筋疲力尽了,但我无法找到一个明确的答案,也无法帮助自己理解到底出了什么问题。作为家庭作业的一部分,我尝试为字符数组(即CString)动态分配内存,并分配一个字符指针变量指向它,然后在结束程序之前删除分配的内存。我只是把我的头绕在指针上,所以我怀疑我对幕后发生的事情的一些理解是不正确的,最后我发现VisualStudio2010给了我堆损坏断点 下面是我试图做的一个简化版本(我的评论表明我认为我在做什么): 通过赋值来初始化数组似乎在某种程度上破坏了我的工作 有人能帮我

我在谷歌上搜索这篇文章已经筋疲力尽了,但我无法找到一个明确的答案,也无法帮助自己理解到底出了什么问题。作为家庭作业的一部分,我尝试为字符数组(即CString)动态分配内存,并分配一个字符指针变量指向它,然后在结束程序之前删除分配的内存。我只是把我的头绕在指针上,所以我怀疑我对幕后发生的事情的一些理解是不正确的,最后我发现VisualStudio2010给了我堆损坏断点

下面是我试图做的一个简化版本(我的评论表明我认为我在做什么):

通过赋值来初始化数组似乎在某种程度上破坏了我的工作


有人能帮我吗?

您正试图删除一个内存块,其中您的“九月”所在的内存块肯定没有在堆中分配,如果您需要初始化预分配的缓冲区,请使用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
上分配一个堆内存,然后通过在非堆字符数组上分配值“九月”来分配一个非堆内存(数据段内存,如果准确的话)

如果尝试删除非堆内存,则会出现错误


使用strcpy(chPtr,“九月”)甚至更好:丢失C并使用
std::string
赋值
chPtr=“九月”不会做你认为它会做的事情。它将静态字符数组
地址分配给变量
chPtr
。当您试图在其上调用
操作符delete[]
时,会出现问题:您试图删除一个静态分配的字符数组

如果希望复制字符,则必须使用字符串复制函数,如

当然,C++中使用C风格字符串的正确方法是不使用C风格字符串。使用标准C++模板之一。< /P> < P> <代码> CHPTR =“九月”;<代码>更改
chPtr
指向的位置。它不再指向分配了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";
您可以看到
p
指向的地址在每次分配时都会发生变化。在空闲存储区(
0068C988
)上分配的块在第三次分配时丢失

如果要分配字符,请执行以下操作

std::strcpy(chPtr, "September");
这包括内存管理、数组和指针的所有注意事项。你真正想做的是:

std::string s = "September";
std::cout << s;
std::string s=“九月”;

std::cout
chPtr=“septer”
不会将任何内容分配给
chPtr
指向的内存,而是将
chPtr
分配给指向另一个保存“septer”的内存。您不能删除此内存。

您指的是数据段。“九月”不是坐在架子上啊,这是有道理的。为了帮助我充分理解这一点,我将如何将一个文字(即“九月”)分配到由<代码>新< /COD>分配的内存中,而不使用STRCYP()?C++对堆、堆和数据段一无所知。代码>“九月”
不是“临时字符串”。这不是分配一个字符串,而是一个指向字符数组的指针。你不能在C或C-like-code上这样做,因为
new char[]
分配一系列字节,而不给它们分配任何值。字节数组没有构造函数,它只是一块内存。您必须使用一些内存复制功能,如
strcpy
memcpy
。但是,您可以在堆上创建
std::string
,并通过
newstd::string(“九月”)
为其分配一个文本。这就是说,
std::string
已经将其内部缓冲区保留在堆上,因此实际上不需要创建基于堆的std::string@isanae我接受你的评论,我对我的答案做了一些修改。我明白了。因此,如果不使用<代码> StcPy< <代码>,将值分配给代码分配的内存,那么我需要(例如)创建一个函数,通过索引(即内存地址由内存地址)循环,手动分配每个字符,没有“堆”,就C++而言(至少不是使用它的方式)。你可能指的是。
00000000
0068C988
00D18B34
std::strcpy(chPtr, "September");
std::string s = "September";
std::cout << s;