参考网站
C++ reference:malloc
C++ reference:new
待学习: malloc/new的实现、 malloc的实现1、 malloc的实现2
原理
实际上,一个堆实际是这样的:
new/malloc都是通过系统调用brk(),sbrk()对堆进行管理的:
int brk(void *addr);
addr:将addr设置为未分配内存的首地址
返回值:成功返回0,失败返回-1。
void *sbrk(intptr_t increment);//brk()“偏移量”版本
increment:
= 0 获取未分配前的内存首地址(也就是已经分配尾地址)
> 0 增加内存空间
< 0 释放内存空间
返回值:未分配前的内存首地址,以字节为单位
区别
具体参考:new和malloc的区别
- malloc()是stdlib.h中的库函数,new是一个运算符;
- new操作符从自由存储区(free store)上为对象动态分配内存空间,而malloc函数从堆上动态分配内存。自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区;
- new和malloc都返回指向分配地址的指针,new的返回类型是一个确切类型的指针(如:int*,double*),而malloc()返回类型只能是void*。
- new内存分配失败时,会抛出bac_alloc异常。malloc分配内存失败时返回NULL;
- new申请内存分配时无须指定内存块的大小,编译器会根据信息自动计算,而malloc则需要显式地指出所需内存的尺寸。
- new在为对象申请内存时,会调用对象的构造函数,在delete时会调用析构函数(new对象数组时必须用delete[]来释放,否则只会调用一次析构函数)。而malloc不会调用构造函数或析构函数;
- new为数组分配空间时有专门的new[]和delete[],而malloc只会返回一块内存地址,不在意里面的结构。
- new可以被重载,而malloc不能;
- new一旦分配,不能再修改分配内存的大小,而malloc分配内存后,如果在使用过程中发现内存不足,可以使用realloc函数进行内存重新分配实现内存的扩充。
测试
//测试new的返回类型
#include<iostream>
using namespace std;
int main()
{
//new int返回值类型时int*,因此会报错
double * p1 = new int;
delete p1;
}
运行结果:
#include<iostream>
#include <stdlib.h> //malloc()所在库
using namespace std;
int main()
{
int *p2 = malloc(4);
//int *p2 = (int*)malloc(4);//正确写法
free(p2);
free(p3);
}
运行结果:
//测试new调用构造函数,delete []调用多次析构函数
#include <iostream>
using namespace std;
class A
{
public:
A(){
cout << "A()" << endl;
}
~A(){
cout << "~A()" << endl;
}
};
int main()
{
A* p = new A[5];
delete[] p;//如果是delete p,只会调用一次~A()
}
运行结果:
//realloc重新分配空间
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *str;
/* 最初的内存分配 */
str = (char *) malloc(15);
strcpy(str, "runoob");
printf("String = %s, Address = %p\n", str, str);
/* 重新分配内存 */
str = (char *) realloc(str, 25); //25是新的大小
strcat(str, ".com"); //之前的内容将会被保留
printf("String = %s, Address = %p\n", str, str);
free(str);
return(0);
}