直接完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#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. 其次是内存泄漏。开辟的内存的地址并没有传递给实参,形参又最后销毁了,同时没有释放内存,函数运行完后申请的内存无法找到,导致最终无法释放,造成内存泄漏
1
2
3
4
5
6
//更合适的代码
void GetMenmory(char** p)
{
*p = (char*)malloc(100);
}

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