一、什么是动态内存管理,为什么会有动态内存管理
动态内存管理顾名思义就是管理内存,但是内存一般都是在变量创建时就已经开辟,但是在使用过程中经常内存不够用,比如一个通讯录,在创建时没有几个人,开辟那么多空间是很浪费的一件事情,所以这时就需要动态内存管理,比如空间不够时就去开辟空间,所以这就是动态内存管理。
动态内存管理也是利用函数去创建和申请内存空间。
二、动态内存函数
1、mallco
void* malloc (size_t size);
这个函数向内存申请一块连续可用的空间,并返回指向这块空间的指针。如果开辟成功,则返回一个指向开辟好空间的指针。如果开辟失败,则返回一个NULL指针,因此malloc的返回值一定要做检查。返回值的类型是 void* ,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己来决定。如果参数 size 为0,malloc的行为是标准是未定义的,取决于编译器。
2、free
void free (void* ptr);
free函数用来释放动态开辟的内存。如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的。如果参数 ptr 是NULL指针,则函数什么事都不做。
int main() { //代码1 int num = 0; scanf("%d", &num); int arr[num] = { 0 }; //代码2 int* ptr = NULL; ptr = (int*)malloc(num * sizeof(int)); if (NULL != ptr) { int i = 0; for (i = 0; i < num; i++) { *(ptr + i) = 0; } } free(ptr); ptr = NULL; return 0; }
使用malloc函数时必须要进行free释放,需要遵守谁开辟的谁释放,开辟地址所使用的指针必需要置为空指针。
3、calloc
void* calloc (size_t num, size_t size);
这个函数和mallco差不多,中间的差距大概就是在与calloc是开辟了空间后把里面的数据全部置为0,而mallco不会。
4、realloc
void* realloc (void* ptr, size_t size);
有时会我们发现过去申请的空间太小了,有时候我们又会觉得申请的空间过大了,那为了合理的时候内存,我们一定会对内存的大小做灵活的调整。那 realloc 函数就可以做到对动态开辟内存大小的调整。
ptr 是要调整的内存地址
size 调整之后新大小
返回值为调整之后的内存起始位置。
这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到 新 的空间。
realloc在调整内存空间的是存在两种情况:情况1:原有空间之后有足够大的空间
情况1 当是情况1 的时候,要扩展内存就直接原有内存之后直接追加空间,原来空间的数据不发生变化。 情况2 当是情况2 的时候,原有空间之后没有足够多的空间时,扩展的方法是:在堆空间上另找一个合适大小的连续空间来使用。这样函数返回的是一个新的内存地址。
三、柔性数组
结构中的柔性数组成员前面必须至少一个其他成员。sizeof 返回的这种结构大小不包括柔性数组的内存。包含柔性数组成员的结构用malloc ()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。
typedef struct st_type { int i; int a[0];//柔性数组成员 }type_a;
int i = 0; type_a *p = (type_a*)malloc(sizeof(type_a)+100*sizeof(int)); p->i = 100; for(i=0; i<100; i++) { p->a[i] = i; } free(p);
使用如上,柔性数组的这样柔性数组成员a,相当于获得了100个整型元素的连续空间。也要记得释放内存.