前言
学习完C语言中的动态内存管理,大家开始利用动态内存管理来去开辟空间,经过一顿狂敲代码后,发现了问题,程序要么崩掉,要么运行不起来。小编现在给大家分享动态内存中常见的练习,如有谬误,欢迎指正
练习1:
void GetMemory(char* p) { p = (char*)malloc(100); } void Test(void) { char* str = NULL; GetMemory(str); strcpy(str, "hello world"); printf(str); }
运⾏Test 函数会有什么样的结果?
敲完代码,运行一下,程序崩掉啦。这里的GetMemory()函数,采用的是值传递,形参是实参的一份临时拷贝。p和str是各自独立的两个指针,GetMemory()函数让p开辟了一个内存空间。但是(重点),p的值最初是在str中拷贝的,拷贝完之后,两个指针没有任何关系。当GetMemory()函数结束后,p的内存就被释放掉了,然后执行srecpy(),此时str仍然是一个空指针,这个程序也就无法被访问。
还有一个问题是,GetMemory()中申请的内存空间没有被释放掉,存在内存泄漏问题。
改进后的代码
void GetMemory(char** p)//形参用二级指针接收,此时p里面存的是str的地址 { *p = (char*)malloc(100);//*p得到str,让str指向新开辟的空间 } void Test(void) { char* str = NULL; GetMemory(&str);//址传递 strcpy(str, "hello world"); printf(str); free(str); str = NULL; } int main() { Test(); return 0; }
运行结果
hello world
这个问题,在日后会经常遇到,需要留意一下。
练习2:
char* GetMemory(void) { char p[] = "hello world"; return p; } void Test(void) { char* str = NULL; str = GetMemory(); printf(str); }
运⾏会有什么样的结果?
数组p是一个局部变量
在 GetMemory 函数之后,数组 p 的内存空间就被销毁了,还给了操作系统,虽然把这个数组首元素的地址返了回去,但此时再通过地址去访问这一块空间,就成了非法访问。
修改后的代码
char* GetMemory(void) { char* p = "hello world"; return p; } void Test(void) { char* str = NULL; str = GetMemory(); printf(str); } int main() { Test(); return 0; }
运行结果
hello world
练习3:
void GetMemory(char **p, int num) { *p = (char *)malloc(num); } void Test(void) { char *str = NULL; GetMemory(&str, 100); strcpy(str, "hello"); printf(str); }
运行结果
hello world
这段代码运行后发现是可以的,但是看到了malloc却看不到free,存在内存泄漏问题
修改后的代码
void GetMemory(char** p, int num) { *p = (char*)malloc(num); } void Test(void) { char* str = NULL; GetMemory(&str, 100); strcpy(str, "hello"); printf(str); free(str); str = NULL; } int main() { Test(); return 0; }
练习4:
void Test(void) { char *str = (char *) malloc(100); strcpy(str, "hello"); free(str); if(str != NULL) { strcpy(str, "world"); printf(str); } }
运⾏会有什么样的结果?
world
代码也是可以运行的
但是依然有错
因为早在开始,就把str给释放了,这块内存权限给了操作系统
在 free 完后没有把 str 置为空,所以 str 还是指向那块空间,此时的 str 已经变成了一个野指针,后面一些列涉及 str 的操作都属于非法访问。
修改后的代码
void Test(void) { char* str = (char*)malloc(100); strcpy(str, "hello"); free(str); str = NULL; if (str != NULL) { strcpy(str, "world"); printf(str); } }