指针做实参,如何修改指针
指针做实参,如果想修改指针的值,必须传指针的指针或者指针的引用。现在来分析下面的C代码:
void GetMemory(char *p)
{
p = (char *)malloc(100);
}
void Test(void)
{
char *str = NULL;
GetMemory(str);
strcpy_s(str, 100,"hello world");
printf(str);
}
请问运行Test 函数会有什么样的结果?
分析:上面的代码试图使用指针作为参数,分配动态内存。该代码会存在两个问题:
1. 内存泄漏。
首先,通过指针作为参数无法成功申请一块动态分配的内存。这是因为,GetMemory()函数获得的是实参指针变量的一个拷贝。因此,它只是将新分配的内存赋给了形参(即实参指针的拷贝)。而实参并没有获得这块内存。在Test()函数中,发现并没有释放str指向内存的语句。但这不是内存泄露的根本原因。即使在程序后面加上一句:
free(str);
内存依然会泄漏。这是因为,str根本没有获得这块内存,而是由形参获得了。而形参是一个栈上的变量。在函数执行之后就已经被系统收回了。这是造成了内存泄漏的根本原因。
要想成功获得分配的内存,可以采用下面的两种方法:
char* GetMemory(char
*p)
{
p = (char *)malloc(100);
return p;
}
上面的代码直接返回新分配的内存。由于内存是在堆上而不是在栈上分配的,所以函数返回后不存在任何问题。
或者:
void GetMemory(char **p)
{
*p = (char *)malloc(100);
}
void Test(void)
{
char *str = NULL;
GetMemory(&str);
strcpy_s(str, 100,"hello world");
printf(str);
}
这种方法是通过指针的指针来分配内存。用这种方法分配内存,传递给函数的是指针地址的一个拷贝,那么*p就是指针本身。因此新分配的内存成功的赋给了做实参的指针。
void GetMemory(char *&p)
{
*p = (char *)malloc(100);
}
void Test(void)
{
char *str = NULL;
GetMemory(str);
strcpy_s(str, 100,"hello world");
printf(str);
}
2. NULL指针引用导致程序崩溃。
由于str并没有获得这块内存,那么str的值依然为NULL,所以strcpy()函数访问了一个NULL指针,直接导致程序崩溃。