控制内存分配

重载new和delete

new和delete实际上是opeartor new和operator delete,我们可以去重载这两个运算符。我们既可以在全局重载,也可以在类内重载。当我们new一个对象,首先会查找类内有没有实现,然后全局,最后才是使用标准库。

这里delete的返回类型都错了,是void而不是void*。

前四个可能会抛出bad_alloc异常。nothrow_t是new头文件里的一个struct,不包含任何成员,并且定义了一个名为nothrow的const,可以通过这个常量来使用下面四个非抛出版本。当我们重载下面四个的时候也必须使用noexcept。

当作为类的成员时,会隐式声明为静态的,因为发生在对象创建前和销毁后因此与数据成员本身无关,是静态的。

对于operator new([])来说,它的返回类型必须是void*,第一个形参类型必须是size_t表示字节数或者数组所需空间大小。在此外,它不可以有默认实参,但是却可以有额外实参,这种有额外实参的new必须通过如定位new的方式来调用。

使用方式:new (形参) type([]);

但是,唯有void operator new(size_t, void);void\ ^*operator\ new(size\_t,\ void^*);不可以被重载,只能被标准库使用,在使用定位new时只传入一个地址时被调用。

对于operator delete([])来说,返回类型是void,第一个形参为void*。

当为类成员时,可以再传入一个类型为size_t的参数表达void*所指向对象的大小。通过虚折构可以根据不同的对象更改不同的大小。

不像其他重载可以重载含义,new和delete我们是指重载了内存分配的方式,但基本含义仍然不变。

实际分配和释放内存

用malloc分配,free释放,定义于cstdlib中。

malloc接受一个待分配字节数size_t类型参数,返回指针或0表示失败。

free接受一个malloc返回的指针。free(0)没有意义。

定位new(placement new)

使用形式:new (place_address)(size_t以外的参数) type ([]) (initializer)/{list}new\ (place\_address)(除size\_t以外的参数)\ type\ ([])\ (initializer)/\{list\}

只有new和type是必须的。

new和delete只负责内存相关的,构造与清除会在其中交予构造或折构函数。

place_address是一个指针。当有这个参数的时候就是定位new,就是在place_address的地方调用构造进行创建,(允许我们在一个特定的、预先分配的内存地址上构造对象),并不进行内存的分配与销毁。并且很重要的是,place_address可以是new的,也可以是其他的,甚至可以指向不是动态内存的。

折构函数可以被显式调用,但是折构函数只负责清除对象而不负责释放对象,因此我们必须手动delete,或者继续使用这块空间放其他的东西。


控制内存分配
https://lhish.github.io/project/hide/控制内存分配/
作者
lhy
发布于
2024年6月30日
许可协议