第一题:
//问:下面test函数会输出什么 #Include<stdio.h> #include<stdlib.h> void GetMemory(char*p) { p=(char*)malloc(100); } void test(void) { char*str=NULL; GetMemory(str); strcpy(str,"hello world"); printf(str); } int main() { test(); }
第一题分析题目程序会崩溃:
1. GetMemory传参数时是用的传值,我们都知道传值是不会改变函数内部的值的。
这就导致了在外部用malloc开辟的空间返回的指向地址的指针无法改变test函数里的str指针。
2.既然不会改变str指针,那str还是NULL,那么在进行strcpy函数拷贝时,会出现*NULL,
我们都知道NULL未知的大小位置,所以对NULL解引用是非法操作,所以程序会崩溃。
3.另外一个错误也算是老生常谈的了,用了动态内存函数申请空间没有用free函数释放空间
还要记得将指针置空。
我们既然都知道了错误原因,那么改掉错误也就十分容易了。
改正1:(传地址调用)
//问:下面test函数会输出什么 #include<stdio.h> #include<stdlib.h> #include<string.h> void GetMemory(char**p)//用二级指针去接收一级指针的地址 { *p=(char*)malloc(100);//*p表示的是一级指针的地址(也就是str的地址),将申请好的内存后, // 返回赋值给str,从而使外部的str的值指向了开辟好的首地址。 } void test(void) { char*str=NULL; GetMemory(&str);//传地址就没问题 strcpy(str,"hello world");//此时str不再是NULL了,而是新申请的首元素地址 printf(str);//打印出hello world free(str); str=NULL;//说烂了,不说了,简称一套带走,嘻嘻!! } int main() { test(); }
改正2:(返回值接收)
//问:下面test函数会输出什么 #include<stdio.h> #include<stdlib.h> #include<string.h> char* GetMemory(char*p) { return p = (char*)malloc(100); } void test(void) { char*str = NULL; str = GetMemory(str);//返回值接收 strcpy(str, "hello world"); printf(str); free(str); str = NULL; } int main() { test(); }
注意:上面的解法中虽然p是局部变量,在栈区上开辟,出了函数,p指针销毁,但动态内存函数申请的空间在堆区,出了函数不会被销毁,且指针p在销毁是已将开辟好的地址传给了str,所以可行。