[C语言]动态内存分配遇上函数-经典错误纠错

发布时间 2023-10-02 13:51:32作者: supdriver0521

题目来自nice2016校招笔试题

直接完整代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void GetMemory(char* p)   //申请内存
{
	p = (char*)malloc(100);  
}

void Test()
{
	char* str = NULL;
	GetMemory(str);
	strcpy(str, "hello world"); //复制字符串
	printf(str);  //输出字符串
}

int main()
{
	Test();
	return 0;
}

分析

推测这段代码的的目的是通过GetMemory函数申请内存,然后把返回的地址存入指针变量str,再把字符串"hello world"复制到str所指向的内存中,最后printf输出

逐步纠错

GetMemory
  1. 首先是传参错误。若在函数内修改外部的一级指针,不能直接将外部一级指针作为实参传入:因为函数会将实参赋给形参,程序运行到大括号外面后,形参被销毁,实参没有变化。所以应该使用char** p二级指针作为形参,储存地址时使用*p\
  2. 其次是内存泄漏。开辟的内存的地址并没有传递给实参,形参又最后销毁了,同时没有释放内存,函数运行完后申请的内存无法找到,导致最终无法释放,造成内存泄漏
//更合适的代码
void GetMenmory(char** p)
{
    *p = (char*)malloc(100);
}

Test
  1. NULL的大问题。假设malloc返回的地址已经存入str,但任然缺少对空指针的判断,导致strcmp中传入了空指针->报错;printf中传入空指针->报错
  2. 没有释放内存->内存泄漏。
//更适合的代码
void Test()
{
    char* str = NULL;
    GetMemory(str);
    if(str == MULL)
    {
        return;
    }
    strcpy(str,"hello world");
    printf("%s\n",str);
    free(str); //防止内存泄漏
    str = NULL; //清除野指针
}