几个经典的动态内存错误笔试题

错误代码展示(一):                                                                                                                       

void GetMemory(char *p)
{
    p = ( char * )malloc(100);
}
void Test(void)
{
    char *str = NULL;
    GetMemory(str);
    strcpy(str ,  "hello world");
    printf(str);
}

试问运行这段代码会有什么样的结果呢? 

答:这段代码中Test函数运行会导致程序挂掉崩溃。该代码存在如下问题:

  1. 对空指针进行解引用:虽然Test函数调用GetMemory函数向内存malloc申请了100个字节大小的空间并且把空间的首地址赋给了P指针,但是由于p指针(形参)是str指针(实参)的一份临时拷贝,所以在返回Test函数时,编译器将P指针销毁了,因此P指针中的地址也会被销毁,因此 str指针仍然是一个NULL(空指针),strcpy函数和printf函数在访问str时,等于是对空指针进行了解引用操作,所以不合法。
  2. 导致内存泄漏:动态内存函数开辟的内存空间没有被释放掉。

对这段代码有俩种办法进行修改 

第一种:

void GetMemory(char** p)
{
    *p = ( char * )malloc(100);
}
void Test(void)
{
    char *str = NULL;
    GetMemory(&str);//让str指针指向动态开辟的内存空间
    strcpy(str ,  "hello world");
    printf(str);
    //释放空间
    free(str);
    str=NULL;
}
int main()
{
    Test();
    return 0;
}

 第二种:

char* GetMemory(char* p)
{
    char* p = ( char * )malloc(100);
    return p;
}
void Test(void)
{
    char *str = NULL;
    GetMemory(str);//让str指针指向动态开辟的内存空间
    strcpy(str ,  "hello world");
    printf(str);
    //释放空间
    free(str);
    str=NULL;
}
int main()
{
    Test();
    return 0;
}

 错误代码展示(二):

char *GetMemory(void)
{
    char p[]="hello world";
    return p;
}
void Test(void)
{
    char *str =NULL;
    str = GetMemory();
    printf(str);
}

试问运行这段代码会有什么样的结果呢? 

答:这段代码中Test函数运行也会导致程序挂掉崩溃。该代码存在如下问题:

  1. 返回栈空间地址的问题:虽然Test函数调用GetMemory函数向内存申请了一块儿数组空间p,但是在GetMemory函数返回的时侯,只是将数组的(首)地址返回去了,并且还把数组这块空间给销毁掉了,因此str在得到数组的地址时,其实本质上是一个野指针,因为它指向的空间以及不存在了。
  2. 野指针解引用:printf(str);对野指针解引用是危险的

 错误代码展示(三):

void GetMemory(char **p, int num)
{
     *p = (char *)malloc(num);
}
void Test(void) 
{
     char *str = NULL;
     GetMemory(&str, 100);
     strcpy(str, "hello");
     printf(str);
}

试问运行这段代码会有什么样的结果呢? 

答:这段代码中Test函数运行也会导致程序挂掉崩溃。该代码存在如下问题:

  1. 内存泄漏:本代码可以带屏幕上打印出 hello ,但是对于malloc所申请的动态内存空间没有释放,造成了内存泄漏的问题。

对这段代码进行修改

  

void GetMemory(char **p, int num)
{
     *p = (char *)malloc(num);
}
void Test(void) 
{
     char *str = NULL;
     GetMemory(&str, 100);
     strcpy(str, "hello");
     printf(str);
     //释放空间
     free(str);
     str=NULL;
}

 错误代码展示(四):

void Test(void) 
{
     char *str = (char *) malloc(100);
     strcpy(str, "hello");
     free(str);
     if(str != NULL)
     {
         strcpy(str, "world");
         printf(str);
     }
}

试问运行这段代码会有什么样的结果呢? 

答:这段代码中Test函数运行也会导致程序挂掉崩溃。该代码存在如下问题:

  1. 野指针的问题:这段代码由于free函数过早的将malloc函数申请的空间释放掉了,而没有及时的将str指针置为NULL,str仍然记得被释放掉空间的地址,放进入if语句后,strcpy函数和printf函数又对野指针解引用,这是不合法的操作。

对这段代码进行修改

void Test(void) 
{
     char *str = (char *) malloc(100);
     strcpy(str, "hello");
    
     if(str != NULL)
     {
         strcpy(str, "world");
         printf(str);
     }

     free(str);
     str=NULL;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陆码农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值