之前面试遇到过这种问题,是c语言的基本功,我觉得还是要记录一下。
1、
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void GetMemory(char *p)
{
p = (char *)malloc(100);
}
int main(int argc, char const *argv[])
{
char *str = NULL;
GetMemory( str );
strcpy( str, "hello world" );
printf( "%s\n",str );
return 0;
}
编译运行结果:编译通过,运行段错误
原因:
GetMemory传入的形参,修改的只是p的副本,p的副本申请了内存,传入的字符串指针并没有变。
GetMemory并不能起到任何作用。每执行一次GetMemory就会泄露一块内存,因为没有用free释放内存。
2、
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *GetMemory( void )
{
char p[] = "hello world";
return p;
}
int main(int argc, char const *argv[])
{
char *str = NULL;
str = GetMemory();
printf( str );
return 0;
}
编译运行结果:编译通过,运行段错误
原因:
GetMemory中的p[]为函数内的局部自动变量,在函数返回后,内存被释放。起不到分配内存的作用。
GetMemory并不能起到任何作用。每执行一次GetMemory就会泄露一块内存,因为没有用free释放内存。
3、
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void GetMemory( char **p, int num )
{
*p = (char *) malloc( num );
}
int main(int argc, char const *argv[])
{
char *str = NULL;
GetMemory( &str, 100 );
strcpy( str, "hello" );
printf( "%s\n",str );
return 0;
}
编译运行结果:编译通过输出正常
但是!~:每执行一次GetMemory就会泄露一块内存,因为没有用free释放内存。
避免了题目一的问题,传入GetMemory的参数为字符串指针的指针,后未判断内存是否申请成功,应加上对内存申请是否成功的判断
4、
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* GetMemory(int num)
{
char* p = (char*)malloc(100);
return p;
}
int main(int argc, char const *argv[])
{
char* str = NULL;
str = GetMemory(100);
strcpy(str, "hello");
printf( "%s\n",str );
return 0;
}
注意和题目2的区别。虽然都是局部变量,但题目用函数返回值来传递动态内存;而题目二return语句返回指向“**栈”**内存的指针,因为该内存在函数结束时自动消亡。
每执行一次GetMemory就会泄露一块内存,因为没有用free释放内存。
5、
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* GetMemory(void)
{
char* p = "hello world";
return p;
}
int main(int argc, char const *argv[])
{
char* str = NULL;
str = GetMemory();
printf( "%s\n",str );
return 0;
}
编译运行输出正确。
但是设计不合理,在main中,str是个只读的内存块,不能修改,若果有strcpy(str, “hello test”);之类的修改str会报内存错误。
【参考资料】高质量C++C 编程指南 林锐(可以邮件问我要)