首页 > 试题广场 >

检查下面代码有什么问题?

[问答题]
检查下面代码有什么问题?
void GetMemory( char *p ) 
{ 
 p = (char *) malloc( 100 ); 
} 
void Test( void )  
{ 
 char *str = NULL; 
 GetMemory( str );  
 strcpy( str, "hello world" ); 
 printf( str ); 
} 
1. 采用传值的方式,并不能改变传入形参的值
2. malloc分配内存后,没有检查是否分配成功
3. 动态分配的内存没有free
发表于 2017-07-30 16:44:44 回复(0)
更多回答
1、GetMemory函数的参数应该用二级指针;
2、main函数中的指针p作为形参传递,会产生指针的拷贝p_cpy传入GetMemory函数中;即传入GetMemory的指针如果是一级指针的话,所分配的内存的地址是给拷贝的指针p_cpy,而不是给p;
3、如果使用二级指针传递,pp作为形参,会产生指针的拷贝pp_cpy,此时pp和pp_cpy都是指向p,所分配的内存的地址自然也就可以传递给*pp(即p)啦!
以上三点仅是说明str并没有分配到内存,是NULL;
发表于 2016-03-03 11:44:01 回复(0)
传参时,实参str与形参p指向相同的内存,而在函数中malloc重新为形参申请了一段内存,
使形参指向新的内存,而实参依然指向原来的内存。

编辑于 2016-09-27 21:24:32 回复(4)
知识点:
  • malloc——向系统申请分配指定size个字节的内存空间,返回类型为void*类型。需强行转换为实际类型的指针。
    eg:int *p;  p= (int *) malloc ( sizeof (int) );
存在问题: 
  • 函数的形参为字符串指针,在函数内部修改形参值并不能真正的改变实参值。在函数中malloc重新为形参申请了一段内存,使得形参指向新的内存,而实参str依然为NULL。
  • 函数结束要对str进行free(),将内存块释放。
 解决问题:
  • 要为指针分配内存,应传入指针的地址,即 GetMemory( &str );
  • 函数的参数应该用二级指针,即 GetMemory( char **p )
  • 此时,p指向str,为*p分配内存即为str分配内存,即 *p = (char *) malloc( 100 );
发表于 2017-05-02 10:09:31 回复(2)
传参时,p指向了“str指向的内存“,malloc重新申请的内存地址付给了p(也就是p指向了新内存),而str指向的内存没有变。
char * GetMemory()
{
	char * p=NULL;
 	p = (char *) malloc( 100 );
	return p;//返回“新分配的内存”的地址
}
void Test( void ) 
{
     char *str = NULL;
     str = GetMemory(); 
     strcpy( str, "hello world" );
     printf( str );
}

编辑于 2016-02-12 10:49:24 回复(3)
void GetMemory( char *p )
函数在内部改变形参值,不改变原传入变量的值
void GetMemory( char *&p )
使用参数引用,可改变原变量的值
函数结束要对str进行free
发表于 2015-12-07 11:50:46 回复(0)

1.动态内存获取应该验空;

2.形参只是实参的一份拷贝,要传值要用指针。如果形参本来就是指针,就要用二级指针;

3.动态内存抓过来要正确放掉,不然内存泄漏;




指针方面多敲代码自己就能理解了,我一开始觉得指针这么烦,一会儿定义指针,一会儿又解引用,而且还有空指针和野指针,乱七八糟的,那为啥要用指针?用值多方便的。


举个例子,这就像你给计算机讲故事(我有一个国外朋友是个美国人,他的名字很长每次说全名很麻烦,但他姓史密斯,为了方便,把他记为s)。这样就相当于你用s指向了你的朋友史密斯,他的类型是美国人。

Americans *s=“Brain-anckonosuytshivredge Smith ”


发表于 2019-08-27 13:29:39 回复(2)
void GetMemory( char *p )
{
 p = (char *) malloc( 100 );
}
我的第一个感觉就是因为该函数没有返回值,所以原来的str地址还是空的,但是指针p所☞的位置
开辟了空间。
还有就是1楼的亮了,真是博大精深!赞!

发表于 2017-05-09 21:01:47 回复(0)

简单的来说就是在传参时,复制了一个和str指向内容相同的p指针,然后传给getmemory(),函数调用完后,p指针就自动消失,最后和str屁事没有,因为传参传的的又不是他自己,函数又没给他开辟空间

发表于 2020-01-18 18:32:28 回复(0)
malloc其函数原型为void *malloc(unsigned int size);其作用是在内存的动态存储区中分配一个长度为size的连续空间。此函数的返回值是分配区域的起始地址,或者说,此函数是一个指针型函数,返回的指针指向该分配域的开头位置。当无法知道内存具***置的时候,想要绑定真正的内存空间,就需要用到动态的分配内存,且分配的大小就是程序要求的大小。
编辑于 2019-07-16 15:31:15 回复(0)
可以把*p看成一个整体,函数只有改变*p才可以达到改变实参的目的。 *p圈起来,只剩char,所以*p改变,只能改变char类型数据。 要想改变char*类型数据,形参要变成char* *p(我故意把*p和char*分开),传入的str要改为&str 这和创建链表的思路差不多 void CreateList(ListNode* *pHead,ListNode* *pEnd) 这样想我感觉比较好理解
编辑于 2019-03-26 10:37:48 回复(0)
传入GetMemory函数内的str值赋给p,随后malloc分配了一个内存给p,但str仍然是NULL。
void GetMemory( char **p )
{
 *p = (char *) malloc( 100 );
}
void Test( void ) 
{
 char *str = NULL;
 GetMemory( &str ); 
 strcpy( str, "hello world" );
 printf( str );
free(str);
str =NULL;
}


发表于 2018-07-23 13:52:37 回复(0)
我只想到了内存泄露,没有看到传值调用……  能力还是有待提升啊
发表于 2017-08-18 17:01:17 回复(0)
我们举个例子
地址                          变量值                                           值
0x00                                                                            NULL
0x01(&s)                      0x00 (s)                                   NULL(*s)
0x02(&p)                      0x00 (p也就是s的地址)            NULL(*p)
后进入函数,只是修改了p的变量值
地址                          变量值                                           值
0x00                                                                              NULL
0x01(&s)                      0x00 (s)                                      NULL(*s)
0x02(&p)                      0x100 (p)                                   NULL(*p)
0x100                          ??                                              ??
所以只是改了p中的内容
如果使用二级指针
地址                          变量值                                           值
0x00                                                                              NULL
0x01(&s)                      0x00 (s)                                   NULL(*s)
0x02(&p)                      0x01 (p也就是s的地址)            0x00(*p)             NULL(**p)
后进入函数,只是修改了p的变量值
地址                          变量值                                          值
0x00                                                                           NULL
0x01(&s)                      0x100 (s)                                 指向了新开辟的100个空间(*s)
0x02(&p)                      0x01(p)                                   0x100(*p)             NULL(**p)
假设100个地址首地址是这个
0x100                          ??                                              ??

编辑于 2017-07-21 15:10:00 回复(0)
运行到strcpy( str, "hello world" );难道不会崩溃。。怎么没人提。
发表于 2016-01-05 18:13:52 回复(1)
ImB头像 ImB
 p = (char *) malloc( 100 ); 没有相应的free函数,所以会造成内存泄露

发表于 2015-11-05 20:34:40 回复(1)
NWU头像 NWU
#include <iostream>

using namespace std;


//传值调用
void GetMemory( char **p )
{
*p = (char *) malloc( 100 );
}
//引用调用
void GetMemory_1(char *&p)
{
p = (char *) malloc (100);
}

int main()
{
char *str = NULL;
char *str1 = NULL;
GetMemory( &str );
GetMemory_1( str1 );
strcpy( str, "hello world" );
strcpy( str1, "hello world1" );
cout<<str<<endl;
cout<<str1<<endl;
free(str);
free(str1);
return 0;
}

发表于 2015-12-20 21:03:37 回复(17)
要改变一个变量的值,要传地址,例如你改变int a的值,你传&a,改变 int *a 你就指针的地址,也就是二级指针
发表于 2016-07-18 14:32:14 回复(12)
void GetMemory(char** p)
{
	*p = (char*)malloc(100);
}
void Test(void)
{
	char* str = NULL;
	GetMemory(&str);
	strcpy(str, "hello world");
	printf(str);
}

发表于 2023-09-02 15:52:54 回复(0)
GetMemery函数只是将形参p的地址改变了,而实际上的实参str并没有改变
发表于 2021-02-03 10:28:53 回复(0)
1.传入形参不能改变形参的值。 2.没有free,造成内存泄露。
发表于 2020-08-31 20:30:20 回复(0)