1.先看一段代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void GetMemory(char *p)
{
p=(char *)malloc(100);
}
void main()
{
char *str=NULL;
GetMemory(str);
strcpy(str,"hello word");
printf(str);
}
运行结果会是怎样呢?
上面的代码会出现内存泄露。
对于它的理解我们可以和函数传参的传值改值结合起来理解。在GetMemory()函数内的确给p在堆上开辟了内存,但执行完该函数后,p将不再指向该段已开辟好的内存。
但是我们所开辟的空间还在,只是无法访问而已。
该如何改正呢?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void GetMemory(char **p)
{
*p=(char *)malloc(100);
}
void main()
{
char *str=NULL;
GetMemory(&str);
strcpy(str,"hello world");
printf(str);
}
形参只要写成指针的指针就可以了。
相当于传地址改值。
2.再来看另外一段代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* GetMemory()
{
char p[]="hello word";
return p;
}
void main()
{
char *str;
str=GetMemory();
puts(str);
}
这样可以输出我们所期待的 hello world 吗?
还是不可以。
在*GetMemory()函数内p在栈上是有内存的,p[]是一个字符数组变量,并给他初始化(系统给p分配空间,再存储hello world),是一个局部变量,该函数执行完后,p会消亡,系统自身将这一部分内存释放,再之后,该部分内存可能会被其他东西占用,所以会输出乱码,并不是我们所期待的hello world。
3.由此我想到了在做链表的题目时,创建链表我也是返回的指针,为什么他就可以正确输出呢?
那是因为在创建链表的函数里,我是用malloc开辟空间的,即在堆上开辟空间的..
看一段代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* GetMemory()
{
char *p;
p=(char *)malloc(20);
gets(p);
return p;
}
void main()
{
char *str;
str=GetMemory();
puts(str);
free(str);
}
在堆上开辟空间时,他不会自动释放该空间,因此即使GetMemory()函数结束使用,该空间仍然有效。只有用户手动释放时,free(),才会无效。
4.再来看一段代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* GetMemory()
{
char *p="hello world";
return p;
}
void main()
{
char *str;
str=GetMemory();
puts(str);
}
这又会输出什么呢?
hello world.
这又是为什么呢?
在GetMemory()函数内,定义了一个字符指针变量,并使它指向一个字符串常量的首地址,在内存中,字符串常量会存储在常量区),该字符串常量所占的内存并没有消亡。所以会输出hello world。
注意第4个和第3个应和第2个相对比,进行理解。

被折叠的 条评论
为什么被折叠?



