malloc与calloc只不过calloc在开辟空间的同时,还会将空间上的数字赋值为0
重点介绍一下realloc
void* realloc (void* ptr, size_t size);
ptr 是要调整的内存地址
size 调整之后新大小
返回值为调整之后的内存起始位置。
这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到 新 的空间。
realloc在调整内存空间的是存在两种情况:
情况1:原有空间之后有足够大的空间
情况2:原有空间之后没有足够大的空间
1,free(p)只是使系统对该空间进行回收,并不是销毁空间,该空间还是存在的。
2,free(NULL)是没有问题的,因为NULL没有指向有效空间
3,free只能用于动态开辟的空间,不能对栈区上的空间进行释放
4,一块空间不能多次释放,假设你释放一次后系统又再一次使用它,当你再次释放的时候,就会破坏其他有效的空间
5,free后一定要将指针设为NULL
主要是当需要结构体中使用可以动态增长的数组时
struct A
{
int a;
int arr[0];
//或者int arr[];
};
柔性数组可以相当于可以动态增长的数组但是在使用时又有些不同
结构中的柔性数组成员前面必须至少一个其他成员。
sizeof 返回的这种结构大小不包括柔性数组的内存。
包含柔性数组成员的结构用malloc ()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小
其实从功能上看,我们单独将数组动态开辟也未尝不可
也可以这样
A* p = (A*)malloc(sizeof(struct A) );
p->a = (int*)malloc(sizeof(int) * 100);
这样同样是在为数组开辟100*4个字节的空间,但是这样做的话在后续内存的释放会比较麻烦,后者要比前者多释放一次空间,当用户在使用我们的函数时候,并不知道做了二次内存分配,用户可能只会释放一次内存,那么就会造成内存泄露,所以我们将结构体的内存及其成员内存一次性分配好,并且返回一个指针的话,用户使用时只需要做一次free就可以了。
同时连续的内存有利于提高访问速度,也有益于减少内存碎片。
(因为所分配的空间时不连续的,而数组占用的时连续空间)