一道考指针的题

  

(1)

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

请问运行Test函数会有什么样的结果?

答:没错,子函数中动态分配内存成功了,但是主函数却得不到这块动态分配的内存的地址。因为char *p作为参数传递时,传递的是指针的值,而非指针本身。也就是说,参数p得到了str的值NULL,然后动态申请了一部分内存,并将首地址覆盖了p的值(NULL),但是这时,str的值仍为NULL.....

(2)

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

请问运行Test函数会有什么样的结果? 
答:子函数中p在栈上创建一个数组,并把字符串常量的值“hello world”赋给了p的数组,当子函数执行完后,其在栈上所占用的内存就释放掉了,p执行的内存是不可预知的内容,所以Test中printf的也就不可预知了。

 

(3) 

Void GetMemory2(char **p, int num) 
{ 
*p = (char *)malloc(num); 
} 
void Test(void) 
{ 
char *str = NULL; 
GetMemory2(&str, 100); 
strcpy(str, "hello");   
printf(str);    
} 

请问运行Test函数会有什么样的结果?
答:可以执行成功,但是内存泄露了。因为子函数的参数为指针的地址,也就是说,主函数中传过来的是str的地址,在子函数中,直接使用的就是str,所以分配及最后在主函数打印都没问题。但是最后没有free,内存泄露了。

 

(4)

void Test(void) 
{ 
char *str = (char *) malloc(100); 
    strcpy(str, “hello”); 
    free(str);      
    if(str != NULL) 
    { 
      strcpy(str, “world”); 
printf(str); 
} 
} 

请问运行Test函数会有什么样的结果?

答:及其危险,因为在free(str)后,并未将str指向NULL,这样的话它就成了野指针(指向随机的一个内存块),这样再将world赋给它,将会造成不可预知的错误。

 

 

对于上面的小程序,想表达的意思就是给子函数传递一个指针,然后在子函数中动态申请内存,再在主函数中使用它。

下面有三种办法可以实现:

(1)

传递指针的值,动态申请,返回指针的值

char* GetMemory(char *p)
{
 p = (char*)malloc(100);
 return p;
}

void test()
{
 char *str = NULL;
 str = GetMemory(str);
 strcpy(str,"hello world");
 printf(str);
 free(str);
 str = NULL;
 return 0;
}

(2)

传递指针本身(指针的地址),动态申请

char* GetMemory(char *p)
{
 p = (char*)malloc(100);
 return p;
}

void test

{
 char *str = NULL;
 str = GetMemory(str);
 strcpy(str,"hello world");
 printf(str);
 free(str);
 str = NULL;
 return 0;
}

 

(3)

引用的方式传递指针的值,动态申请

void GetMemory(char*& p,int num) 
{ 
    p=(char*)malloc(num); 
} 
void test
{
	char *str = NULL;
	 GetMemory(str,100);
	//printf(str);
	strcpy(str,"hello world");
	printf(str);
	free(str);
	str = NULL;
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值