我的C ++程序需要一块未初始化的内存和一个指向该块的void*
指针,以便我可以将它提供给第三方库。我想将块生命周期的控制权传递给库,因此我不想使用std::vector
。当库完成块时,它将调用我必须提供的回调,并将解除分配块。在C语言中,我会使用malloc()
以及之后的free()
。
在C ++中,我可以稍后分别致电::operator new
或::operator new[]
以及::operator delete
或operator delete[]
:
void* newBlock = ::operator new( sizeOfBlock );
// then, later
::operator delete( newBlock );
看起来::operator new
和::operator new[]
具有完全相同的签名和完全相同的行为。 ::operator delete
和::operator delete[]
也是如此。我不应该做的唯一事情是将operator new
与operator delete[]
配对,反之亦然 - 未定义的行为。除了我选择哪一对以及为什么?
答案 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_cast
将char*
转换为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 ...