Getmemory的几个经典的关于内存的笔试题:
<NO 1>
void GetMemory( char *p )
{
p = (char *) malloc( 100 );
}
void Test( void )
{
char *str = NULL;
GetMemory( str );
strcpy( str, "hello world" );
printf( str );
}
【
运行错误
】传入GetMemory(char* p)函数的形参为字符串指针,在函数内部修改形参并不能真正的改变传入形参的值。执行完
char *str = NULL;
GetMemory( str );
后的str仍然为NULL。
实质:编译器总是要为每个参数制作临时副本,指针参数p的副本是_p,编译器使_p=p。如果函数体内的程序修改了_p的内容,就导致参数p的内容作相应的修改,这就是指针可以用作输出参数的原因。在本例中,_p申请了新的内存,只是把_p所指的内存地址改变了,但是p丝毫未变。所以GetMemory并不能输出任何东西。事实上,每执行一次GetMemory就会泄露一块内存,因为没有用free释放内存。
<NO 2>
char *GetMemory( void )
{
char p[] = "hello world";
return p;
}
void Test( void )
{
char *str = NULL;
str = GetMemory();
printf( str );
}
【
运行错误
】GetMemory中的p[]为函数内的局部自动变量,在函数调用返回后,内存已经被释放。所以打印出来的数据不是我们要求打印的数据,但是返回的指针指向的地址是一定的。这是很多程序员常犯的错误,其根源在于不理解变量的生存期。用调试器逐步跟踪Test,发现执行str=GetMemory语句后str不再是NULL指针,但是str的内容不是“hello world”,而是垃圾。
<NO 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 );
}
【
运行正确,但有内存泄露
】
<NO 3>
避免了题目一的问题,传入GetMemory的参数为字符串指针的指针,但是在GetMemory中执行申请及赋值语句