一、有问题代码
void GetMemory(char* p)
{
p = (char*)malloc(100);
}
void Test(void)//str 和 p是不同的指针变量
{
char* str = NULL;
GetMemory(str);//传递的是指针变量 即 NULL
strcpy(str, "hello world");
printf(str);
}
int main()
{
Test();
return 0;
}
上述代码 :
1. 内存分配未影响到调用函数中的指针
在C语言中,函数参数传递是值传递。 GetMemory 函数的形参 p 是 Test 函数中 str 的一个副本。
GetMemory 函数中 p = (char*)malloc(100); 只是让 p 指向了新分配的内存,但 Test 函数中的 str 指针仍然是 NULL 。这意味着 Test 函数中的 str 并没有因为 GetMemory 函数中的操作而指向新分配的内存。
2. 解引用空指针
由于 str 仍然是 NULL ,当执行 strcpy(str, "hello world"); 时,程序会尝试将字符串 "hello world" 复制到 NULL 指针所指向的内存位置。
这是一种未定义行为,通常会导致程序崩溃,因为 NULL 指针不指向任何有效的内存空间。
3. 内存泄漏
在 GetMemory 函数中分配的内存,由于没有正确地传递给调用者( Test 函数中的 str 未指向该内存),导致这块内存无法被释放。
随着程序运行,这部分内存将一直被占用,从而产生内存泄漏。
使 GetMemory 函数内对形参 p 的内存分配操作未影响 str 指针,导致 str 仍为 NULL ,执行 strcpy 时引发解引用空指针的未定义行为致程序可能崩溃,且 GetMemory 中分配的内存因未正确传递给调用者而产生内存泄漏。
二、改正后
1、使用指针的指针
void GetMemory(char** p)
{
*p = (char*)malloc(100);
}
void Test(void)//str 和 p是不同的指针变量
{
char* str = NULL;//str是char* 类型的指针
GetMemory(&str);//传递的是地址
strcpy(str, "hello world");//将字符串复制到str
printf(str);
}
int main()
{
Test();
return 0;
}
2、使用返回值(还阔以这么写)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* GetMemory() {
return (char*)malloc(100);
}
void Test(void) {
char* str = GetMemory();
if (str!= NULL) {
strcpy(str, "hello world");
printf("%s\n", str);
free(str);
}
}
后面这两种修正方法中,都确保了 Test 函数中的 str 指针能够正确指向分配的内存,并且在使用完内存后进行了释放,避免了内存泄漏。同时,还添加了对指针是否为 NULL 的检查,以防止空指针引用。