带字符串赋值的双重释放或损坏错误

时间:2014-03-26 05:01:09

标签: c++ string corruption double-free

我在这里输入字符串有错误。这是我们编码的函数,用于存储从url获取的数据。 编辑:datanode结构

  struct node
  {
    string url;
    std::string* data;
    struct node* next;
    struct node* prev;
  };


  void RandomCache::cachePage(string* page_data, string url)
  {
    datanode *page_node= (datanode*)malloc(sizeof(datanode));
    page_node->url = url;
    page_node->data = page_data;
    page_node->next=NULL;
    page_node->prev=NULL;

    insertNode(page_node);

  }

行page_node-> url = url导致Double free或损坏,数据按值传递,而不是通过引用传递。任何人都可以指出什么是错的?

谢谢,我把结构变成了一个类,问题完全解决了。谢谢!但我仍然对此感到疑惑,为什么使用malloc的结构内存管理在C ++中是一个问题。结构在c ++中经常使用。

3 个答案:

答案 0 :(得分:1)

当你使用malloc而不是new时,不会调用datanode的构造函数,因此在page_node->处调用std :: string。 url不会让它的构造函数被调用。因此,当调用其equals运算符时,page_node-> url将被搞乱。

具体来说,在内部,std :: string类包含一个指向实际包含字符串字节的内存块的指针。执行字符串赋值时,将调用用于字符串的重写的equals运算符。它的第一个工作是为对象应该包含的旧字符串释放现有内存。如果它被正确构造,它将不包含任何内容,但在这里它将只包含随机数据,因此它会释放一些随机内存。

解决方案是,如果要在对象内部存储字符串(或任何带有构造函数的C ++类),请完全构造对象并使用new。

试试这个:

datanode *page_node= new datanode();

用删除替换你的free()。​​

另一方面,page_data有不同的问题。当您将指针传递给在别处分配的字符串时,您需要注意对此的内存管理,原始字符串不会超出范围或在使用此指针时销毁。

答案 1 :(得分:1)

  

字符串分配的双重免费或损坏错误

如果您遇到这些错误,很可能是您的程序遇到堆内存损坏。

一般情况下,在您的进程中加载​​的某些DLL /模块已经发生真正的损坏之后,通常会检测到堆损坏。因此,很可能其他一些代码出错并且上面的代码只是受害者。因此,我建议您使用一些动态工具来快速理解错误,并在问题发生时解决。从您的描述中,您的程序也可能存在某种内存损坏。

我认为我以前的帖子也可能对这个问题有用。如果您的程序是特定于Windows的(WinDBG / PageHeap),您应该看到以下链接:

https://stackoverflow.com/a/22074401/2724703

如果您的程序是Gnu / Linux特定的(Valgrind),您应该看到以下链接:

https://stackoverflow.com/a/22085874/2724703

答案 2 :(得分:1)

您展示的代码完全正确C(因此,正确的C ++)。

问:你的树的根存储在哪里?作为班级中的成员变量" RandomCache"这对" cachePage()"都是可见的和" insertNode()"?全局变量?

建议:

1)确保你的" cachePage()"中的malloc()空间的datanode指针。 function是你实际上自由的相同的指针。从您已经展示的代码中可以看出," datanode * page_node"在" cachePage()"之外的 NO 可见性 - 当你最终" free()"指针,你实际上释放了随机的,未初始化的内存。

2)Valgrind在这里非常有用。试试吧!

3)在释放指针后,始终将指针设置为NULL。