您的位置:首页 > 职场人生

【经典面试题】有关指针、内存空间如何申请调用的问题

2015-08-13 23:33 567 查看
完整的程式运行代码如下:

[code]#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;

char *GetMemory(char *&p, int num)  //注意这里为什么传入指针p的地址?
{
p = (char *)malloc(sizeof(char)*num);

//p = new char[num];
return p;

}
int main(void)
{
char *str ;
GetMemory(str, 100);
strcpy(str, "hello");
cout << str << endl;
return 0;
}


然后,题主搜寻了一些Hr们经常忽悠大家的,好,菜已经准备好,磨刀霍霍。。。。

错误一: 仅仅是值得改变

[code]void GetMemory( char *p )
{
 p = (char *) malloc( 100 );
}
void Test( void ) 
{
 char *str = NULL;
 GetMemory( str ); 
 strcpy( str, "hello world" );
 printf( “%s”,str );
}


分析原因:

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

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

3. new的时候有可能内存出错,应该在p = (char ) malloc( num ); 后判断内存是否申请成功,应加上:

if ( *p == NULL )

{

  …//进行申请内存失败处理

} //一个良好程序员要注意防呆措施

4. 动态创建的内存没释放

[code]错误分析:
 错认为 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的值改变。   
}


修改一:

[code]void GetMemory2(char **p)变为二级指针. 
void GetMemory2(char **p, int num) 
{ 
*p = (char *)malloc(sizeof(char) * num);   //其实就相当于char *p=(char*)malloc(sizeof(char)*num)
} 
void Test(void)
{ 
char *str=NULL; 
GetMemory=(&str); //传入指针的地址
strcpy(str,"hello world"); 
printf(str); 
}


修改二: 修改返回类型

[code]char *GetMemory()
{ 
char *p=(char *)malloc(100); 
return p; 
} 
void Test(void){ 
char *str=NULL; 
str=GetMemory();
strcpy(str,"hello world"); 
printf(str); 
}


然后就是各种错误出现了,

[code]试题a:
char *GetMemory( void )
{ 
 char p[] = "hello world"; 
 return p; 
}

void Test( void )
{ 
 char *str = NULL; 
 str = GetMemory(); 
 printf( str ); 
}


试题a中

char p[] = “hello world”;

return p;

的p[]数组为函数内的局部自动变量,在函数返回后,内存已经被释放。这是许多程序员常犯的错误,其根源在于不理解变量的生存期。

[code]试题b:
void GetMemory( char **p, int num )
{
 *p = (char *) malloc( num );
}

void Test( void )
{
 char *str = NULL;
 GetMemory( &str, 100 );
 strcpy( str, "hello" ); 
 printf( str ); 
}


试题b中

1、GetMemory避免了试题4的问题,传入GetMemory的参数为字符串指针的指针,但是在GetMemory中执行申请内存及赋值语句

p = (char ) malloc( num );

后未判断内存是否申请成功,应加上:

if ( *p == NULL )

{

 …//进行申请内存失败处理

}

2、试题b的Test函数中也未对malloc的内存进行释放。

[code] 试题c:

void Test( void )
{
 char *str = (char *) malloc( 100 );
 strcpy( str, "hello" );
 free( str ); 
 ... //省略的其它语句
}


试题c中

存在与试题b同样的问题,在执行

char str = (char ) malloc(100); 后未进行内存是否申请成功的判断;另外,在free(str)后未置str为空,导致可能变成一个“野”指针,应加上: str = NULL;

对内存操作的考查主要集中在:

  (1)指针的理解;

  (2)变量的生存期及作用范围;

  (3)良好的动态内存申请和释放习惯。

[code]再看看下面的一段程序有什么错误:

swap( int* p1,int* p2 )
{
 int *p;
 *p = *p1;
 *p1 = *p2;
 *p2 = *p;
}

  在swap函数中,p是一个“野”指针,有可能指向系统区,导致程序运行的崩溃。在VC++中DEBUG运行时提示错误“Access Violation”。该程序应该改为:

swap( int* p1,int* p2 )
{
 int p;
 p = *p1;
 *p1 = *p2;
 *p2 = p;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: