重新分配由operator new()分配的内存空间?

3

当使用operator new()方式分配内存时,是否有可能重新分配该内存?

char* buf = new char[60];

C++ FAQ指出,new分配的内存不能通过realloc调整大小,那么如何正确地重新分配由new分配的内存?


1
C++的new/delete系统默认情况下没有类似于realloc的操作。如果您需要使用new,那么您可能真正需要的是一个std::vector。重复问题链接:http://stackoverflow.com/questions/1179669/realloc-function-that-would-work-for-memory-allocated-using-new-instead-of-reallo - wkl
根据这个问题,似乎没有这样的函数。 - BlackBear
4个回答

7

正确的做法是不要这样做。

如果之前的分配不够大,只需分配新的内存。

或者使用 std::vector,它可以非常高效地包装所有这些功能。


6

正确的方法是根据数组的特定用途使用 std::vectorstd::string--让 C++ 为您处理分配。

如果你必须使用 new,那么你需要重新分配内存并复制数据。这个简单的模板函数可以帮助你完成这些基本操作:

template <typename T>
T *GrowArray(T *oldArray, size_t oldCount, size_t newCount) {
    T *newArray = new T[newCount];
    if (oldArray) {
        std::copy(oldArray, oldArray + std::min(oldCount, newCount), newArray);
        delete[] oldArray;
    }
    return newArray;
}

请注意,在大多数实现和大多数用例中,这基本上就是 realloc() 所做的事情,只不过没有类型安全性。如果这看起来效率低下,那么 realloc() 可能并没有做得更好。

+1 如果您能正确翻译此内容并提供正确(一目了然)的代码,但是将此方法称为“GrowArray”有点误导。调用后原始指针无效。 - John Dibling
@John - 没有适当的文档是无法解决的。 :) - James
4
您对于realloc的评论并不正确。虽然realloc可能执行与您发布的函数类似的操作,但它同样有可能使用特定于操作系统的知识,在不复制数组内容的情况下“扩展”数组。例如,在某些Linux版本中,由malloc返回的内存块是以程序员无法访问但内部实现可以访问的大小变量开头的。当调用realloc时,实现可以检查此变量以查看是否可以扩展数组而不必复制所有内容。 - Charles Salvia
1
@Charles:我知道,我只是在简化表述。对于尺寸增加不多或者不跨越页面边界的调用,是的,操作系统能够优化并且不会重新分配内存。但是,对于更大的重分配,我的评论仍然成立。 - Jonathan Grynspan
@John:在成功调用realloc之后,原始指针也不再有效。 - Jonathan Grynspan

2

1
唯一的方法是进行第二个新建,复制内容,然后删除旧的内存块:
char *tmpbuff = new char[70];
memcpy(tmpbuff, buff, 60 * sizeof(char));
delete [] buff;
buff = tmpbuff;

(不...C++并不等同于STL,所以没有STL的生活也是可以的 :-))


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接