#include<stdio.h> #include<string.h> #include<malloc.h> int Malloc(char *p) { return (NULL!=(p=(char *)malloc(100*sizeof(char))));//这个成为调用完后,又成野指针了??? //return 0; } int main() { char *p1=NULL; Malloc(p1); strcpy(p1,"helo"); puts(p1);//输出,这个函数用得还很少 return 0; }
分析问题:
在int Malloc(char *p)中的*p实际上市主函数p的一个副本,编译器总是要为函数的每个参数制作临时副本。在本例中p申请了心的内存,知识把p所指的内存的地址改变了,但是p1丝毫未变。因为函数Malloc没有返回值,因此p1并不指向p所申请的那段内存。事实上,每执行一次Malloc就会申请一块内存,但申请的内存却不能有效释放,结果是内存一直被独占,最终造成内存泄露。
如果一定要用指针参数去申请内存,那么应该采用指向指针的指针,传p1的地址给函数Malloc.
代码如下:
#include<stdio.h> #include<string.h> #include<malloc.h> int Malloc(char **p) { return (NULL!=(*p=(char *)malloc(100*sizeof(char)))); //return 0; } int main() { char *p1=NULL; Malloc(&p1); strcpy(p1,"helo"); puts(p1);//输出,这个函数用得还很少 return 0; }
还可以用函数返回值来传递动态内存,这种方法更加简单:(用到指针函数)
#include<stdio.h> #include<string.h> #include<malloc.h> char *Malloc(char *p) { if(NULL!=(p=(char *)malloc(100*sizeof(char)))) return p; } int main() { char *p1=NULL; p1=Malloc(p1); strcpy(p1,"helo"); puts(p1);//输出,这个函数用得还很少 return 0; }
再看下面这个有意思的问题:
#include<stdio.h> #include<string.h> #include<malloc.h> char *Malloc() { char p[]="hello world"; return p; } int main() { char *p1=NULL; p1=Malloc(); //strcpy(p1,"helo"); puts(p1);//输出,这个函数用得还很少 return 0; }
这段代码输出的是什么呢?
答案是:乱码,因为Malloc此时返回的是指向“栈内存”的指针,该指针的地址不是NULL,但是其原来的内容已经被清除,新内容不可知。(这个为什么呢?)