函数原型:
void *operator new(size_t); //allocate an object
void *operator delete(void *); //free an object
以类A为例:
class A
{
public:
A(int v) : var(v){
fopen_s(&file, "test", "r");
}
~A(){
fclose(file);
}
private:
int var;
FILE *file;
};
当我们用new创建一个A类的指针数组时,new返回的是指向内存空间的A类型的指针
class *pA = new A(10);
当我们用delete释放掉类对象的时候
delete pA;
1.申请和释放基本数据类型的数组空间
这里会发现,创建数组和创建单个对象的不同,这里new 和 delete变成了:
type *name = new type[ ];
delete [] name;
在上面的例子中,释放string类型数组空间时实际上先为10个string对象分别调用析构函数,再释放掉为10个string对象所分配的所有内存空间;而释放int类型数组空间时,因为int是内置类型不存在析构函数,所以直接释放掉了为10个int类型变量分配的所有空间。
因此,非内置类型数据用new type[] 来动态分配内存时,必须保存数据的维度,以确定在析构时需要调用对象析构函数的次数。C++的做法是在分配数组空间时在前面多分配了4 Bytes 大小的空间,专门保存数组的维度,在delete的时候根据数据维度调用析构函数,最后再释放所有内存空间。
以创建pA类对象数组为例说明 Type *name = new Type[] 和 delete[] name的运行机制
首先为对象数组分配内存空间:
class A *pAa = new A[3];
delete [] pAa;
背后的工作是:
正如前面所说:依次为数组中每个对象调用析构函数,调用析构函数的总次数是由调用new库函数时开辟的内存空间的前4 Bytes 中保存的数据决定的;调用delete[] name 库函数时,其参数不是指针name的值(也是第一个数组元素的地址),而是这个地址值减去4 Bytes
void* malloc(size_t size);
int *p = (int *) malloc(sizeof(int));
案例:
//0.包含头文件
//1.定义一个char* 指针变量p,并分配10个字节内存空间(字符数组)
char *p = (char *)malloc(sizeof(char));
//2.将字符数组中的内容全部修改为0
memset(p, 0, 10 * sizeof(char));
//3.复制一段字符串到p指向的数组空间(长度要比所分配的内存小)
strcpy(p, "hello ");
//4.用realloc扩充p指向的内存空间
p = (char*)realloc(p, 20 * sizeof(char));
//4.在原字符串后面再拼接一段字符
strcat(p, "world");
//5.释放空间
free(p);
参考文献:
C/C++——C++中new与malloc的10点区别
C++读书笔记—malloc()函数的注意点及使用示例