C语言进阶——5动态内存管理(2)

4. 几个经典的笔试题

来自于书籍《高质量C/C++编程》

4.1 题目1:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.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:GetMemory函数内部创建指针p申请了100字节的空间,动态申请了内存,但是没有释放,会存在内存泄露。
问题2:Test函数调用,传递了一个指针str,str传给p的时候,p是str的临时拷贝,有自己独立的内存空间,当GetMemory函数内部申请空间之后,地址存放在p中,str依然是NULL
问题3:当GetMemory函数返回之后,调用strcpy()函数,相当于访问NULL指针,形成了非法访问内存。

如何修改为正确的代码

修改1

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char* GetMemory()//修改1
{
   
    char *p = (char*)malloc(100);
    return p;

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

    free(str);
    str = NULL;
}
int main()
{
   
    Test();
    return 0;
}

在这里插入图片描述

修改2

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void GetMemory(char** p)//修改2
{
   
   * 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;
}

在这里插入图片描述

上面的两个代码都没有解决内存泄露的问题,只是解决了非法访问内存的问题,
我们在malloc内存之后就应该养成free的习惯。

4.2 题目2:

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

在这里插入图片描述

分析:这个地方的问题,我们一般称为返回栈空间地址的问题
它是由于。p在函数GetMemory()调用完成之后,就销毁了。
虽然我们拿到了p存放的地址就是“hello world”的首字符地址,
但是函数调用结束之后,为p[ ]开辟的空间就已经交还给操作系统了
我们在main函数中还要对其进行访问,是属于非法访问了,访问的内容,就是随机值,可能是我们的“hello world”,也可能是其他任意值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值