有必要删除动态结构内容,然后删除结构本身吗?

Necessary to delete dynamic struct contents, and then the struct itself?

#include <cstring>
using namespace std;

struct Product {
   char *     name;
   float      price;
};

int main() {
    Product * bread = new Product;
    bread->name = new char[6];
    bread->name = "bread";

    delete[] bread->name; //!!!THE ERROR OCCURS ON THIS LINE!!!
    delete bread;
}

给我以下错误:

*** Error in `./out': munmap_chunk(): invalid pointer: 0x0000000000400824 ***

我的问题是是否有必要删除 bread->name,或者删除 bread 是否会为我解决这个问题。如果需要删除 bread->name,为什么当我尝试这样做时程序会崩溃?

其实问题出在这里:

bread->name = "bread";

name 分配一个新数组后,您将该指针分配给一个完全不同的值 - 一个恰好存在于只读内存中的值。因此,当您删除它时会出现错误:您正在尝试 delete [] 一个您未分配的数组。

关键问题是你不想分配指针 name,你想填充刚刚分配的数组的内容——你想要填充 name 指向 的内容。为此,strcpy:

strcpy(bread->name, "bread");

或者真的,因为这是 C++:

struct Product {
   std::string  name;
   float        price;
};

Product bread;
bread.name = "bread";
int main() {
    Product * bread = new Product;
    bread->name = new char[6];
    bread->name = "bread"; // <- Error! Overwriting the pointer value!

    delete[] bread->name; // <- Error! Trying to free read-only memory where "bread" is stored...
    delete bread;
}

基本上,您是用 "bread" 的常量字符数组覆盖动态分配的字符数组 new char[6]。去掉动态分配就不用删了

当您编写 "bread" 时,编译器会获取这些字母并将它们存储在只读存储器中。每次你写 "bread" 并尝试分配它时,你实际上是在分配一个指向只读内存的指针,或者一个 const char*.

当您分配动态数组时,您将动态分配内存的地址存储在 bread->name 指针中,但随后您用 只读内存的地址覆盖了它不允许免费。因此编译器抱怨它。

在您的代码中,由于您不再拥有指向动态分配内存的指针,new char[6],您将无法再释放它,并且还会发生内存泄漏。

我会这样做(考虑到您对使用字符串的限制)并假设您真的想要动态分配:

int main() {
    const char* breadStr = "bread";
    int len = strlen(breadStr);

    Product * bread = new Product;
    bread->name = new char[len + 1];
    strncpy(bread->name, breadStr, len + 1); // Copy the string and the [=11=] (hence the +1)

    delete[] bread->name; // no more error!
    delete bread;
}

如果不需要动态分配,那么您可以这样做:

int main() {
    Product * bread = new Product;
    bread->name = "bread";

    // You don't have to delete the bread->name since it is NOT dynamically allocated but is in your read-only memory.
    delete bread;
}

但我真的更愿意使用@Barry 建议的字符串在 C++ 中完成所有这些操作。