(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;
}