使用哪个 - “operator new”或“operator new []” - 在C ++中分配一块原始内存?

时间:2010-03-23 07:18:12

标签: c++ memory-management

我的C ++程序需要一块未初始化的内存和一个指向该块的void*指针,以便我可以将它提供给第三方库。我想将块生命周期的控制权传递给库,因此我不想使用std::vector。当库完成块时,它将调用我必须提供的回调,并将解除分配块。在C语言中,我会使用malloc()以及之后的free()

在C ++中,我可以稍后分别致电::operator new::operator new[]以及::operator deleteoperator delete[]

void* newBlock = ::operator new( sizeOfBlock );
// then, later
::operator delete( newBlock );

看起来::operator new::operator new[]具有完全相同的签名和完全相同的行为。 ::operator delete::operator delete[]也是如此。我不应该做的唯一事情是将operator newoperator delete[]配对,反之亦然 - 未定义的行为。除了我选择哪一对以及为什么?

4 个答案:

答案 0 :(得分:7)

new与单个对象一起使用,将new[]与一组对象一起使用。所以,例如:

int* x = new int; // Allocates single int
int* y = new int[5]; // Allocates an array of integers

*x = 10; // Assignment to single value
y[0] = 8; // Assignment to element of the array

如果你要做的就是分配内存缓冲区,那么分配一个char数组,如下所示:

int bufferlen = /* choose a buffer size somehow */
char* buffer = new char[bufferlen];
// now can refer to buffer[0] ... buffer[bufferlen-1]

但是,在C ++中,您应该将std::vector用于任意数组,并且应该将std::string用于要解释或用作字符串的字符数组。

没有理由明确调用::operator new::operator new[],而不是使用普通语法进行这些调用。对于POD和原始类型(例如char),不会进行初始化。如果您需要获得void*缓冲区,只需使用static_castchar*转换为void*

答案 1 :(得分:1)

C ++ new运算符优于C malloc()free()的优势在于,如果没有足够的内存,前者会抛出异常,而不是返回NULL

关于为字符缓冲区选择新的(大小)和新的[],我主张后者,因为它不太可能让后来维护代码的人感到惊讶,即char* buf = new char[size]delete[] buf

缓冲区中的值不会被初始化,也没有范围检查 - 您必须构建一个不错的C ++对象来为您执行此操作,或者使用现有对象,例如std::vector或{{ 1}}。

答案 2 :(得分:1)

这个问题无法得到明智的解答。

首先,据说程序“需要”一块未初始化的内存,但是从给出的代码示例中,似乎程序“需要”一块未初始化和UNTYPED内存,看起来不是很C ++或OO。

其次,std :: vector提供对类型内存块的唯一和自动控制,该块可根据其用途改变或不改变大小。如果在堆上创建std :: vector实例并使用原始指针跟踪,就像任何其他C或C ++对象(如void *内存块)一样,则可能会失去此控件。

第三,这个内存块的用途是什么?对此的答案可能会也可能不会决定使用operator new或operator new []。在这个程序的设计中,对这个内存块有一个单一的解释吗?您需要什么所有权语义,如果有的话?等等。

答案 3 :(得分:0)

用于将内存分配给数组/列表使用new []而不是使用new ...