使用 Malloc 为 STL 列表分配内存?

Using Malloc to allocate memory to STL list?

提问人:user124 提问时间:3/20/2021 更新时间:3/21/2021 访问量:248

问:

我正在尝试使用 malloc 将内存分配给 stl 列表。我使用新的工作正常,如下所示:

typedef pair<int, int> iPair;
list< pair<int, int> > *adj;
adj = new list<iPair> [V];

但是如果我使用 malloc 而不是 new,就会抛出分段错误。

adj=(list<iPair> *)malloc(sizeof(list<iPair>)*V);

为什么 malloc 不能用于为 STL 容器分配内存?

C++ STL Segmentation-Fault malloc New-Operator

评论

0赞 Peter 3/20/2021
因为构造一个(或任何具有非平凡构造函数的类的实例)比使用和强制转换结果为其分配内存要多得多。操作员会照顾到没有的额外需求。在代码中,后续使用 that 假定它实际上指向一个正确构造的集合(它没有)将具有未定义的行为。list<iPair>malloc()newmalloc()adjlist<iPair>

答:

2赞 Hatted Rooster 3/20/2021 #1

因为来自 C,而 C 没有类的概念,因此没有构造函数的概念。 分配内存并调用相应的构造函数,仅分配内存。mallocnewmalloc

1赞 fabian 3/20/2021 #2

你可以这样做,但它的做法有点不同。基本上,您需要确保您使用的内存已初始化。 但是返回未初始化的内存。malloc

可以使用 placement new 在所选的内存位置初始化列表对象。删除对象时要格外小心:

分配

void* memory = std::malloc(sizeof(list<iPair>) * V); // uninitialized memory

if (memory == nullptr)
{
    // allocating the memory may fail
    throw std::bad_alloc();
}
list<pair<int, int>> *adj = static_cast<list<pair<int, int>> *>(memory);

size_t initializedCount = 0;

// constructors may throw, so we need to make sure
// already initialized objects are freed in case this happend
try
{
    while(initializedCount < V)
    {
        adj = new (adj[initializedCount])list<pair<int, int>>();
        ++initializedCount;
    }
}
catch(...)
{
    // make sure destructors are called for objects initialized already
    for (size_t i = 0; i < initializedCount; ++i)
    {
        (adj +i)->~list<pair<int, int>>();
    }
    
    // free the memory we allocated ourselves & rethrow
    std::free(memory);
    throw;
}

删除

// release the memory
for (size_t i = 0; i < V; ++i)
{
    (adj + i)->~list<pair<int, int>>();
}

// free the memory we allocated ourselves & rethrow
std::free(memory);