C++删除[]崩溃

C++ delete[] crashes

本文关键字:崩溃 删除 C++      更新时间:2023-10-16

我正在编写一个C++程序,它将字符串存储在字符串数组中,当数组已满时,我使用下面的代码调整数组大小,为更多项目腾出空间。但有时(并非总是)它在"delete[]temp;"行崩溃,我不知道为什么以及如何修复它。请帮忙。

我找了很多,但在任何地方都找不到答案。当我调试时,它说"无效指针",但当我以前在那里存储数据而还没有释放它时,它怎么会无效呢?

这是我的代码:

if(item_cnt >= (arr_size - 1))
{
    int oldsize = arr_size;
    string * temp;
    arr_size *= 2;
    temp = arr;
    arr = new string [arr_size];
    memcpy(arr, temp, oldsize * sizeof(temp));
    delete[] temp;
}

除非您必须坚持当前的方法,否则我建议使用向量来保持字符串。它会为你管理所有的内存。

这里有一个例子:

#include <vector>
#include <string>
int main()
{
   std::vector<std::string> arrayOfStrings;
   arrayOfStrings.push_back("Hello World!"); // To Add Items
   string value = arrayOfString.at(<some index>); // To Retrieve an Item you can also use the [] operator instead of the at method
   return 0;
}

memcpy是问题的根源。每个人都说"不要用它",但让我解释一下为什么这是一个极端糟糕的主意。

首先,什么是c++字符串,它是如何发挥魔力的?它基本上是一个可变长度的字符数组,它通过在每个字符串对象中保持一个指针来实现这一壮举,该指针指向分配给保存这些字符的内存。随着字符串的增长或收缩,内存将被重新分配。正确复制字符串需要对内容进行"深度复制"。

现在,转到您的代码:

arr = new string [arr_size];

这将创建一个空字符串对象数组。因为它们是空的,所以内部指针通常为null。

memcpy(arr, temp, oldsize * sizeof(temp));

在这里,坏事发生了。这实际上并不是创建原始字符串的副本,只是覆盖了内部表示。因此,新旧字符串都指向相同的字符数据。现在真的搞砸了,发生了这样的事情:

delete[] temp;

我们删除了这些旧字符串,但这也释放了它们正在使用的字符内存。因此,这些字符串的"新"副本指向的是实际释放的内存。我们现在有一场车祸等着发生:字符数据可以被重新用于任何事情,当我们再次尝试删除字符串时,操作系统有望发现你正在尝试释放尚未分配的内存。

您的数组应该是真正的

vector<string>

这是实现动态大小数组的推荐方法。通过使用vector,您可以避免手动重新分配/复制内容的必要性,并避免像您所拥有的那样的问题。

混合使用旧式和新式内存操作总是个坏主意。。。这里使用memcpynew/delete。请注意,delete[]还为数组的每个元素调用dtor。。。

编辑:ctor-->dtor

hth

马里奥