关于内存的笔试题

From: http://www.51testing.com/?uid-10851-action-viewspace-itemid-73167

#include <stdlib.h> #include <stdio.h> #include <string.h> void GetMemory(char *p) { p = (char *)malloc(100); } void Test(void) { char *str = NULL; GetMemory(str); strcpy(str, "hello world!/n"); printf(str); } int main() { Test(); return 0; }

1,调用GetMemory( str )后, str并未产生变化,依然是NULL.只是改变的str的一个拷贝的内存的变化   

2,strcpy( str, "hello world" );程序运行到这将产生错误。

3,malloc的时候有可能内存出错,应该在*p = (char *) malloc( num ); 后判断内存是否申请成功,应加上:
   if ( *p == NULL )
   {
     ...//进行申请内存失败处理
   }

4,动态创建的内存没释放。

错误分析:

错认为 GetMemory(char *p)中的 p“就是” GetMemory(str)中的str。但p“不是”str,它只是“等于”str 。
就象:  
int a = 100;  
int b = a;   // 现在b等于a  
b = 500;     // 现在能认为a = 500 ?    

显然不能认为a = 500,因为b只是等于a,但不是a! 
当b改变的时候,a并不会改变,b就不等于a了。   
因此,虽然p已经有new的内存,但str仍然是null !

GetMemory(str); // 把str传进去,str是一个指针,而他实际上是一个int void GetMemory(char *p) // p是str的一个副本 { p=(char *)new char[100]; // p的值改变,但是str的值并没有改变。 } //而双重指针为什么就可以了呢: GetMemory(&str); //把str的地址传进去 void GetMemory(char **p) // p是str地址的一个副本 { *p = (char *)new char[100]; // p指向的值改变,也就是str的值改变。 } //修改方法1:(推荐使用这种方法) void GetMemory2(char **p)变为二级指针. void GetMemory2(char **p, int num) { *p = (char *)malloc(sizeof(char) * num); } void Test(void) { char *str = NULL; GetMemory = (&str); strcpy(str,"hello world"); printf(str); } //修改方法2: char *GetMemory() { char *p=(char *)malloc(100); return p; } void Test(void) { char *str = NULL; str = GetMemory(); strcpy(str,"hello world"); printf(str); }

 

第二题:

#include <stdlib.h> #include <stdio.h> #include <string.h> char* GetMemory2(void) { char p[] = "hello world!"; return p; } void Test2(void) { char *str = NULL; str = GetMemory2(); printf(str); } int main() { Test2(); return 0; }

 

答案很简单,1 运行过程中会出现错误 2 会输出 乱码

题目看似不难,但程序员,尤其是初级的程序员在写代码时很容易犯的一个毛病。


C语言中,实参变量和形参变量之间的数据传递是单向的“值传递”方式,指针变量作函数参数也要遵循这一原则。调用函数不能改变实参指针变量的值(即指针的地址),但可以改变实参指针变量所指变量的值。

 

程序1就试图改变 str 的值,肯定不成功,getmemory执行完后,str还是NULL,所以在执行strcpy时,程序试图给NULL的指针赋值,会发生运行时错误。

 

程序2的问题在于 getmemory函数试图返回局部变量的地址。众所周知,局部变量的生命只存在于该函数体内,一旦离开该函数体,该局部变量便在内存中消失,所以str得到的只能是乱码。当然也不排除在某些特定的编译器上会输出“hello,world”字样。但严格的按照标准C来说,这种写法也是不被允许的

 

Visual C++ Concepts: Building a C/C++ Program
Compiler Warning (level 1) C4172

returning address of local variable or temporary

A function returns the address of a local variable or temporary object. Local variables and temporary objects are destroyed when a function returns, so the address returned is not valid.

Redesign the function so that it does not return the address of a local object.

The following sample generates C4172:

// C4172.cpp // compile with: /W1 /LD //为什么会出现这样的现象呢? float f = 10; const double& bar() { // try the following line instead // const float& bar() { return f; // C4172 }

你可能感兴趣的:(function,null,float,编译器,returning,variables)