malloc 、calloc、realloc

malloc和free

c库分别提供了两个函数,malloc和free,分别用于执行动态内存分配和释放。

malloc 、calloc、realloc

这个函数向内存申请一段连续可用的内存,并返回指向这块空间的指针。

如果开辟成功,则返回一个指向开辟好空间的指针。同时,malloc实际分配的空间有可能比申请的要大,但取决于编译器。

如果开辟失败,则返回一个NULL指针,所以,对返回指针做好检查,确保是空还是非空。

由于malloc返回值为void *,所以可以转换为其他任何类型的指针,malloc并不知道申请的类型,具体的在使用时决定。

如果size为0,malloc的行为是未定义的,取决于编译器。

free函数用于释放动态开辟的内存:

malloc 、calloc、realloc

如果free的参数是NULL,不会产生什么效果。

如果free的参数是不是动态开辟的,则结果是未定义的。

malloc 、calloc、realloc

calloc

malloc 、calloc、realloc

calloc的功能是为num个大小为size的元素开辟一块空间,并把空间每个字节初始化为0,其余和malloc功能一样。

malloc 、calloc、realloc

realloc

realloc函数用于修改一个原先已经分配的内存块大小。使用这个函数,可以使一块内存扩大或缩小。

malloc 、calloc、realloc

memblock是要调整的内存块地址,size是调整后的大小,返回值为调整后的内存起始地址。

这个函数在调整原内存块大小的基础上,还会将原来的内存块中数据移到新的空间。

realloc在调整内存空间存在两种情况:

1.原空间后有足够的空间:要扩展的内存直接追加在原有内存后,原来空间内存数据不发生变化。

2.原有空间后没有足够大的空间:在堆上重新找一个合适的连续空间来使用,这样realloc返回的是一个新的内存地址。

malloc 、calloc、realloc

常见的动态内存错误

1.对NULL指针的解引用

malloc 、calloc、realloc

错误原因:如果申请失败为NULL,那么就不可对p解引用。所以在申请内存后一定要判断是否为空。

2.对动态开辟空间的越界访问

malloc 、calloc、realloc

3.对非动态开辟内存使用free释放

malloc 、calloc、realloc

之前讲道,free的参数是不是动态开辟的,则结果是未定义的。

4.使用free函数释放动态开辟的一部分

malloc 、calloc、realloc

free函数释放的是动态开辟的全部空间

5.对同一段动态空间多次释放

malloc 、calloc、realloc

释放一次后,尽管内容还在,但对那段空间已没有使用权    ,所以也就没有权限再次释放。

6.动态内存空间忘记释放(内存泄漏)

malloc 、calloc、realloc

忘记释放不再使用的动态开辟空间会造成内存泄漏。内存泄漏随程序退出就不存在。

注:动态开辟的空间一定要正确释放。

说明下列题错误原因,并改正

例1:

malloc 、calloc、realloc

我们知道,在调用一个函数时,会形成栈帧,同时,函数形参会形成临时变量,形参是实参一份临时拷贝,尽管值相同,但位置不同,所以申请的空间对str并没有影响,即str依然为空。另外,没有free(p),也没有严重p是否为空。

改为:(没有验证和Free)

malloc 、calloc、realloc

或者

malloc 、calloc、realloc

例2

malloc 、calloc、realloc

错误原因:char p[ ]是在fun的栈帧上开辟空间,retrun后空间将会被释放,将会变为随机值。

改为例1第二种方法。

例三

malloc 、calloc、realloc

free(str),free后str不为空,但是对内存空间没有使用权限。应该在程序最后free(str)。