删除在 C++ 中使用 malloc 分配的 std::string 数组

Deleting an array of std::string allocated with malloc in C++

这是我的问题的跟进:

因为我已经实施了 Tony D 解决方案,所以我已经使用 mallocstd::string 的数组分配了内存,然后使用 [=] 为每个元素创建了 std:string 16=] 根据:

void* TP = malloc(sizeof (string) * SS);
for (int i = 0; i < SS; i++) {
  new (&((string*)TP)[i]) std::string(Token[i]);
}

(Token 是一个 vector<string>SS 是一个 int)

I know this is not recommended, I know it is not elegant, I know there are many other solutions for this array creation and filling, but I need to do it this way

我现在遇到的问题是数组删除。当我分别创建每个 std::string 但使用 malloc 为数组分配时,在我的析构函数中我写了:

for (int i = 0; i < SS; i++) {
  delete (&((string*) TP)[i]);
}
free(TP);

但是当运行时,free(TP)控告一个"double free or corruption"。

通过评论 free(TP) 我解决了运行时的问题(隐藏了真正的问题),但我需要确保释放所有内存,因为这可能会导致 class 内存泄漏.

那么,删除 TP 的每个元素是否足以释放所有内存?根据我的理解,malloc 已独立分配内存,它需要独立于 std::string 元素;但是,为什么我会收到此错误消息?

你在 malloc 分配的块上对 运行 std::string 的构造函数进行了新的放置,但是你正在使用 delete 这将运行 析构函数并尝试释放内存(你不想在这里做第二个,因为你正在释放 free())。

您想 运行 手动析构函数,像这样...

for (int i = 0; i < SS; i++) {
  (&((string*) TP)[i])->~string();
}
free(TP);

首先,让我们清理一下您的代码。我建议您远离 void* 数组类型。然后你可以这样做,这更容易阅读,尤其是在 new() 运算符上:

std::string* TP = (std::string*) malloc(sizeof (std::string) * SS);
for (int i = 0; i < SS; i++) {
  new (&TP[i]) std::string(Token[i]);
}

现在,要释放字符串,你必须直接调用它们的析构函数,不要使用 delete(没有像你这样的 placement-delete 运算符假设):

for (int i = 0; i < SS; i++) {
  TP[i].~string();
}
free(TP);

现在,话虽如此,您显然可以访问 std::vector,因此没有充分的理由改用 malloc()

std::vector<std::string> TP(SS);
for (int i = 0; i < SS; i++) {
  TP[i] = Token[i];
}

或:

std::vector<std::string> TP;
TP.reserve(SS);
for (int i = 0; i < SS; i++) {
  TP.push_back(Token[i]);
}

或:

std::vector<std::string> TP(Token.begin(), Token.begin()+SS);