动态内存开辟

来源:互联网 发布:用手机看淘宝价格走势 编辑:程序博客网 时间:2024/05/29 16:56

提出动态内存分配的背景

通常我们使用数组的时候,必须用一个常量来指定数组的长度,同时它的内存空间在编译时就已经分配好了。但有时候数组的长度只有在运行的时候才知道,所以提出解决方案就是提前申请出一块较大的数组。有缺陷:1、人为因素大,如果在声明时长度还是太小,那么就会发生数组越界。2、如果实际使用的元素比较少但申请大一点就会浪费内存。

malloc、calloc、realoc和free

malloc()

作用:向系统申请分配指定size个字节的的空间。函数原型:`void* malloc(size_t size);`

这个函数向内存申请一块连续可用的空间,并返回指向这块空间的指针。
1、如果开辟成功,则返回指开辟好空间的指针。
2、 如果开辟失败,返回一个NULL指针,所以对于malloc的返回值一定要检查。
3、返回值类型为void,所以它不知道所开辟空间的类型,所以使用时要强制类型转换。
4、如果参数size为0,malloc行为是未定义的,取决于编译器。

》》free用来做空间的回收和释放。函数原型为:void free(void* ptr);
*注意:
-申请了内存空间后,必须检查是否分配成功。
- 如果ptr指向的空间不是动态开辟的,就不可以用free来释放。
- 如果ptr是NULL指针,则函数什么都不做。
- free和malloc成对出现,如果没有释放就会引起内存泄漏。造成这一部分内存没有被使用但是系统一直以为被使用着,就会不断的向系统申请内存,系统内存就会越来越少。
- free之后,记得要将指针置成空。防止后面程序不小心用了他;
这里写图片描述

calloc()

1、函数原型:void* calloc(size_t n, size_t size);
//在内存中分配n个大小为size的连续空间

2、函数返回一个纸盒箱分配起始地址的指针;如果分配不成功就返回NULL.
3、他和malloc区别:
1)他再放回指向内存指针之前把空间初始化成0.
2)请求内存数量不同。

realloc()

优点:它的的出现让动态内存管理更加灵活。对于申请的内存过大或者过小,它能更加合理的分配内存

函数原型void* realloc(void* ptr, size_t size);

ptr是要调整的内存地址。size是调整之后的新大小。返回值是调整后的内存的起始值。函数在调整原来内存空间大小的基础上,还将原来内存中的数据移动到新的空间。调整内存空间时有两种情况:1、原有空间后有足够的空间2、原有空间后没有足够的空间。

针对两种情况不同的解决方案:
这里写图片描述

柔性数组

结构体中最后一个元素或许是未知大小的数组,这就叫柔性数组成员。

typedef struct st{    int i;    int a[0];}type_a;//可能报错,改为下面typedef struct st{    int i;    int a[];}type_a;

柔性数组的特点:
*结构体中柔性数组成员前至少有一个其他成员。
*sizeof求结构体大小时并不包括柔性数组的大小。
*包含柔性数组成员的结构体用malloc函数时,分配的内存应该大于结构体的大小,来适应柔性数组的预期大小。
*便于释放