【经典笔试题】动态内存管理

test1:

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;
}

请问执行上面代码,会出现什么结果?

解析:运行该段代码时,程序会崩溃

答案:调用Test函数时,在Test函数内部又调用Getmemory函数,即使在Getmemory函数内部申请空间,返回的该空间的起始地址给p,然而p并未返回,str仍为NULL。拷贝 "hello world"到str内部,将会导致程序崩溃。

改正:可以将p申请的空间返回。

test2

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

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

请问执行上面代码,会出现什么结果?

解析:运行该程序时,可能会出现乱码。

这是因为在调用GetMemory函数时,p是一个数组,在栈空间上申请内存,即使返回p,用str指针来接收,此时str指针指向了p的地址,但是在调用Getmemory完成后,p所在的空间会被释放,所以str指向的空间是一块未知的空间,使用该空间也造成了非法访问,空间内的内容我们是不知道的。

改正:可以将char p[] 改成char *p, 这样创建的空间就算再常量区,而不是再栈区,出了该函数也不会再销毁该空间。

test3

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

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

请问执行上面代码,会出现什么结果?

解析: 运行该段代码,会打印hello。

就算能运行hello,但是在使用完申请的空间后,并没有释放申请的空间,会造成内存泄露

改正:free(str); str = NULL;

test4


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

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

请问执行上面代码,会出现什么结果?

解析:输出world。

然而,即使会打印world,str是在使用一块不属于自己的空间,因为在第一次拷贝hello之后,对str指向的空间进行了释放,该空间不再属于str,str已经成为野指针。但是str仍然存着这块释放掉的空间的起始地址,所以进入判断语句的时候,该语句不再起到能够阻止str进入的效果,随后str使用的空间是属于操作系统的空间,非法使用空间会有很大的安全隐患。

改正:在free(str);后面加上 str = NULL;

最后:附上c内存分配的几个主要区域。

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

邓富民

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

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

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

打赏作者

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

抵扣说明:

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

余额充值