0

我在这里的字符串分配有错误。这是我们编写的用于存储从 url 获取的数据的函数。编辑:数据节点结构

  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++ 中使用非常频繁。

4

3 回答 3

1

看到您使用的是 malloc 而不是 new,不会调用 datanode 的构造函数,因此 page_node-> url 处的 std::string 不会调用它的构造函数。因此, page_node-> url 将被搞砸当它的等号运算符被调用时。

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

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

尝试这个:

datanode *page_node= new datanode();

并将您的 free() 替换为 delete 。

另一方面 page_data 有不同的问题。当您传递一个指向在别处分配的字符串的指针时,您需要注意它的内存管理,当可以使用这个指针时,原始字符串不会超出范围或被破坏。

于 2014-03-26T05:15:47.287 回答
1

字符串分配双重释放或损坏错误

如果您遇到这些错误中的任何一个,则很可能您的程序遇到了堆内存损坏。

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

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

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

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

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

于 2014-03-26T05:18:36.307 回答
1

您显示的代码是完全正确的 C(因此也是正确的 C++)。

问:你的树根存储在哪里?作为对“cachePage()”和“insertNode()”都可见的“RandomCache”类的成员变量?全局变量?

建议:

1)确保您在“cachePage()”函数中的malloc()空间的数据节点指针与您实际释放的指针相同。从您显示的代码中,“datanode *page_node”可能在“cachePage()”之外没有可见性 - 当您最终“free()”指针时,您实际上是在释放随机的、未初始化的内存。

2) Valgrind 在这里可能非常有用。试试看!

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

于 2014-03-26T05:29:06.283 回答