【问题标题】:Why would <list> element cause segmentation fault in an object using memory from malloc()为什么 <list> 元素会在使用 malloc() 内存的对象中导致分段错误
【发布时间】:2014-10-05 03:29:25
【问题描述】:

我有这个(简化的)C++ 类:

class node{
public:
    int num;
    list<int> iplist;   
};

然后我为它动态分配内存:

node* node1 = (node*) malloc( sizeof(node) );

可以用node1-&gt;num,完全没问题。但是(node1-&gt;iplist).push_back(10)会导致分段错误。我把它改回:

node* node1 = new node;

它再次正常工作,包括(node1-&gt;iplist).push_back(10)。 我已经用谷歌搜索了答案,意识到这可能是因为malloc() 没有初始化元素。但是,我仍然对使用malloc() 时如何初始化&lt;list&gt; 元素感到困惑。

【问题讨论】:

  • malloc 不运行构造函数。您的程序表现出未定义的行为,通过使用一块未初始化的内存,就好像它是一个有效的、完全构造的 node 实例一样。为什么你首先要使用malloc
  • 不要在 C++ 代码中使用malloc
  • “但我仍然对使用 malloc 时如何初始化元素感到困惑” 你不应该那样做,这本质上就是 new 的用途。现代 C++ 甚至禁止使用 new 以支持 make_uniquemake_shared。如果必须将内存分配与初始化分开,则必须使用placement-new手动调用构造函数:node* node1 = static_cast&lt;node*&gt;(malloc(sizeof(node))); new(static_cast&lt;void*&gt;(node1)) node();(包括&lt;memory&gt;)。
  • 关于这个问题的 许多 个重复项:"Accessing member of a C++ object allocated with malloc?"
  • @IgorTandetnik 因为我使用 C 而不是 C++,所以我只想在 C++ 中尝试一下,然后我遇到了这个问题。

标签: c++ malloc new-operator dynamic-memory-allocation


【解决方案1】:

如果您想使用malloc() 来分配您的对象,最可靠的方法是为您的对象重载new 运算符。

class node{
public:
    int num;
    std::list<int> iplist;

    void * operator new (size_t sz) { return malloc(sz); }
    void operator delete (void *p) { free(p); }
    void * operator new[] (size_t sz) { return malloc(sz); }
    void operator delete[] (void *p) { free(p); }
};

由于这些重载,使用newnew[] 将导致调用malloc() 以获取动态分配请求的内存。调用deletedelete[] 将使用free() 释放内存。

【讨论】:

  • 这个答案比使用放置new 更可靠的原因是放置new 要求您在调用free() 之前显式调用对象的析构函数。这个答案还允许您的对象由智能指针正确管理,而无需您定义自定义删除器。
【解决方案2】:

如果你想对 c++ 对象使用 malloc, 您必须使用“新位置”:

void *p = malloc( sizeof(node) );
node* node1 = new (p) node;
node1->iplist.push_back(10);

【讨论】:

    猜你喜欢
    • 2020-03-14
    • 1970-01-01
    • 1970-01-01
    • 2021-07-18
    • 2020-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-31
    相关资源
    最近更新 更多