动态内存管理

动态内存分配
一、C语言内存分配
一、malloc
1、按字节分配内存空间,分配的内存空间不初始化
2、返回类型为void*
3、函数只有一个参数
原型:void* malloc(size_t size);//size是字节个数

二、calloc
1、按字节分配内存空间,分配的内存空间进行初始化为0
2、返回类型为void*
3、函数有二个参数,按类型字节大小和个数开辟内存空间
原型:void* malloc(size_t count,size_t size);//count是个数,size是类型大小

三、realloc
1、动态调整内存大小
2、按字节调整内存大小
2、返回原类型void*  void* realloc(void* ptr,size_t newsize);//ptr所要开辟内存的指针,newsize开辟的字节数
3、函数有二个参数,调整内存空间的指针和所要调整的大小
4、当原指针为空时,同于malloc开辟内存空间
5、当原指针不为空时,
(1)指针处有足够的的内存空间,则直接进行扩容,增大内存空间,原指针地址不变
(2)指针处无足够的内存空间,则重新寻找一块足够的内存空间,并把数据拷到新空间中,释放就旧空间,返回新空间地址。原指针地址发生改变
(3)无足够内存空间返回NULL,数据据丢失。所以建议不要使用原指针接收返回的地址,而用临时指针接收返回的地址,空间开辟成空(非NULL),再指向临时指针
防止数据丢失。
问题:realloc若所要开辟的内存空间小于原内存空间,则结果为多少?开辟0个空间则会是怎样的?
答:若指定的空间小于原空间,则空间会缩小,截除后部分的数据,返回原指针。开辟空间大小为0时,释放原空间返回NULL
注:不管使用那种方式管理内存空间,都需对返回值进行判断,判断空间是否开辟成功,成功返回非NULL,失败返回NULL;
释放内存空间---->free()
开辟的内存空间只能整块释放,不可部分释放。即释放的指针与开辟空间返回的指针必须相同。

C++动态内存管理
开辟内存---->new
1、new自动计算类型大小,按个数开辟内存空间,返回类型为对应的指针类型
2、new和delete为操作符不为函数
3、new和delete的底层是使用malloc和free实现的。

使用方法:
开辟一个int类型的空间
p1 = new int; --------------->delete p1
开辟一个int类型的空间,初始化为1
p2 = new int(1); ------------>delete p2
开辟3个int类型对象的空间,注次数是调用3次构造函数,最终也会调用3次析构函数
p3 = new int[3]; ------------>delete []p3
new 类型[] 开辟内存空间时会多开辟4个字节的空间,用于在头部保存开辟内存空间的个数,返回时向后偏移4个字节的空间,析构时会再向前偏移4个字节释放空间。
所以delete释放空间时,必须与new开辟的方法对应,否则会因空间释放位置不正确导致出错。
new和free也不可混用,否则可能会出现内存泄露的危险
因为:对于自定义类型的对象,在定义时会调用构造函数进行初始化。销毁时会调用析构函数进行销毁。
析构时会先清理类内部成员的空间,后释放对象空间,防止内存泄露。若使用free释放空间,则可能由于类内部成员空间未释放,导致内存泄露

注:虽然使用new---->free操作内置类型不会出错,但也不要这样使用。这样容易导致误解和可读性低。
不出错是由于编译器对内置类型进行了优化,未调用构造函数,和析构函数。

其它类型接口:
void* operator new(size_t size);
void* operator new[](size_t size);
void* operator delete(void* ptr);
void* operator delete[](void* ptr);
注:以上函数不是重载关系,是特列
new = operator new + 构造函数 = malloc+抛异常
delete = operator delete + 析构 = free+抛异常
//假设开辟10个空间
new xx[10] = operator new[] + 10次构造 = malloc(sizeof(xx)*10)+抛异常
delete []_a = operator delete[] + 10次析构 = free+抛异常
空间开辟与释放方法不匹配,是否会导致出错,主要看是否会多或少释放4个字节的空间问题。会就会导致程序崩溃。
计算机判断空间或数组越界访问的方法是,多开辟几个字节的空间并初始化为某个值,如0xcccccccc,当检测到这些值被修改时,则认为越界。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值