2015-05-17 38 views
1
#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->名称,或者如果要删除的面包会照顾这对我。如果有必要删除面包 - >名称,为什么程序崩溃时,我试图做到这一点?

+0

只是FYI:我只使用char数组,因为这个类的教授不允许我们使用字符串。 –

回答

8

这个问题其实从这里茎:

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"; 
+0

Upvoting为*,因为这是C++ *此外,我没有... – nonsensickle

3
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; 
} 

基本上你覆盖的动态分配的字符数组new char[6]"bread"恒定的字符数组。删除动态分配,您不必删除它。

当您编写"bread"时,编译器将采用这些字母并将它们存储在只读存储器中。每次写入"bread"并尝试分配它时,您都有效地将指针分配给只读内存或const char*

当你分配你的动态数组,你保存在bread->name指针动态分配的内存的地址,但你与你不允许释放只读存储器的地址改写它。因此,编译器正在抱怨。

在您的代码中,由于您不再具有指向动态分配内存的指针,因此您不能再释放它,并且还会发生内存泄漏。

我会做这样的(假设您在使用字符串限制),并假设你真正想要的动态分配:

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 \0 (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++中完成所有这些。

+0

“但我真的更喜欢使用@Barry建议的字符串来完成C++中的所有操作。” ME TOO!谢谢你的帮助! –