目录
前言
今天学习了一道经典的动态内存分配题,本文详细叙述了这道动态内存分配题的解题思路与过程。
因为作者初学C语言,本文不可避免的出现错误与纰漏,如果读者发现错误的话可以在评论区指出。
一、题目
1.下列代码存在什么问题?请指出问题并做出相应的修改。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void getmemory(char* p)
{
p = (char*)malloc(100);
}
void test(void)
{
char* str = NULL;
getmemory(str);
strcpy(str, "hello world");
printf("str");
}
int main()
{
test();
return 0;
}
答案:
1.运行代码会出现崩溃的现象
2.程序存在内存泄漏的问题
下面我们逐步分析该代码的运行
1.主函数运行时调用test()函数
2.test函数
3.getmemory函数
4.运行完getmemory函数后
因为p指针是局部变量,所以当getmemory函数运行完时,该局部变量被删除,又因为实参str与形参p为值传递,所以p指针变化无法影响str指针,也就是说str指针依然是空指针,
综上所述,由于str指针是空指针,所以当调用strcpy函数时,直接导致该程序崩溃。
而且由于p指针被删除导致动态开辟空间无法找到,该动态开辟空间也未被释放,这又可能导致内存泄漏。
二、解决方法
1.将值传递改为址传递
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;
}
int main()
{
test();
return 0;
}
解析:将str指针的地址传给p指针,那么*p就等价于str指针,所以此处getmemory函数实现的功能就相当于str指针指向在堆区开辟的100个字节的内存空间,当拷贝功能实现后,再释放str指针指向的内存空间,并将str置为NULL。
2.返回p指针
char* getmemory(char* p)
{
p = (char*)malloc(100);
return p;
}
void test(void)
{
char* str = NULL;
str = getmemory(str);
strcpy(str, "hello world");
printf(str);//直接打印
free(str);
str = NULL;
}
int main()
{
test();
return 0;
}
解析:p指针指向在堆区开辟的100个字节内存空间,并将p指针返回,使用str指针接收p指针,此时str指针指向在堆区开辟的100个字节内存空间,在拷贝功能完成后,释放str指针指向的内存空间,并将str指针置为NULL。