
malloc函数
malloc函数的返回值为void*类型

内存管理函数操作的内存是在堆区空间

malloc函数使用示例

free(p)相当于值传递,不能改变p本身。
free只是释放了空间,释放后p依然指向原地址,故需要手动置NULL。
calloc函数
calloc可以指定开辟n个指定类型的空间,开辟后初始化开辟空间数据为0。
只有calloc开辟空间时会初始化空间。像malloc和realloc开辟空间后的数据为随机值。

realloc


若realloc开辟失败,原开辟空间位置找不到且原空间没有释放,故需要用另一个指针接收,
确认开辟成功后再将新空间的起始地址赋给p。且只有calloc会初始化空间,realloc和malloc不会初始化空间。

realloc函数的参数为NULL时,等价于malloc函数

动态分配的常见错误
1.对NULL指针的解引用操作
开辟空间有可能失败,如果不去判断malloc函数的返回值直接赋值,就有可以对NULL指针的解引用操作。

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

如果越界访问程序会崩溃

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

上述代码问题1:如果对非动态开辟内存使用free释放,程序会崩溃

上述代码问题2:如果p的指向发生改变,则原开辟空间就找不到了,即出现内存泄漏问题。
动态开辟空间的释放


上述代码如果不用free主动释放,则直到程序结束,由操作系统回收。
4.用free释放部分空间

用free释放部分空间,程序会崩溃。
5.对同⼀块动态内存多次释放

如果连续free(p)两次,程序就会崩溃。
但free(p)一次后就将p置空指针则再次free(p)就不会报错,因为free(NULL)则free函数什么都不干。
6.动态开辟内存忘记释放(内存泄漏)

p是一个局部变量,函数结束之后就会将p销毁,就再也找不到开辟的空间了。
习题1

p是str的一份临时拷贝

修改方法(不考虑在GetMemory函数中开辟空间失败的情况)
方法1

申请完空间记得要释放空间(free(str); str = NULL;)
方法2

直接不要参数,直接返回一个指针。

习题2


GetMemory函数调用返回后(原空间被销毁),该函数的函数栈帧开辟空间将被printf函数开辟栈帧空间覆盖,故原p指向的空间为随机值。
简单例子(返回栈空间地址)

修改方法

习题3

运行后正常打印hello
上述代码存在的问题:
1.动态开辟的空间没有释放。
2.在GetMemory函数中开辟空间最好要判断一下是否开辟成功。
修改方法

习题4

原开辟空间使用完释放后没有将str置为空指针,此时str就是野指针,使用则造成非法访问
修改方法
free函数释放完空间后记得要将原来指针置为NULL。

柔性数组


























