m0_57182604 2024-04-30 08:58 采纳率: 0%
浏览 3

Malloc释放空间,栈空间与堆空间

img


指针变量a存储的不是malloc的返回值地址吗,而指针变量a的空间是调用函数栈空间里的空间,不是在调用结束后把这个地址赋给p,p是那个栈空间里的,执行结束后,那这个p里面存的地址不是释放了吗?那为什么释放堆空间时还要写free(p)啊?

  • 写回答

5条回答 默认 最新

  • 专家-皆知 2024-04-30 08:58
    关注

    参考免费微信小程序:皆我百晓生 作答,经由专家-皆知整理回复,如问题解决,望采纳;如仍有疑问,请评论回复。

    你的问题涉及C语言中的内存管理,特别是栈空间与堆空间的区别,以及mallocfree的使用。让我们一步步解答你的疑惑。

    首先,理解栈空间和堆空间的概念是关键:

    • 栈空间:自动分配和释放,用于局部变量,其生命周期与包含它们的函数调用相同。当函数调用结束,栈上的局部变量(包括指针本身)就会被自动销毁。

    • 堆空间:通过malloccallocrealloc等函数动态分配,由程序员负责释放,使用free函数。分配的内存可以在函数调用结束后继续存在,直到明确地被释放。

    针对你的代码示例,我们来详细分析:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char* print_malloc() {
        char *a = (char*)malloc(100); // 在堆上分配空间
        strcpy(a, "I am print_malloc func"); 
        puts(a);
        return a;
    }
    
    int main() {
        char *p; // 在栈上声明一个指针
        p = print_malloc(); // p 指向堆上由 malloc 分配的空间
        puts(p); 
        free(p); // 释放堆上由 p 指向的内存
        return 0;
    }
    
    1. print_malloc函数执行时,它在堆上分配了一块大小为100字节的空间,并将这块空间的地址赋给了局部指针变量a。这里,a本身是在栈上的,但它的值是一个指向堆上内存的地址。

    2. 函数执行完毕后,局部变量a(位于栈上)确实会被销毁,但是它之前指向的堆内存并没有自动释放,因为堆内存的生命周期不由函数调用决定,而是由程序员手动管理。

    3. main函数中的p接收到print_malloc返回的地址时,p也指向了那块堆上的内存。即使print_malloc函数已经结束,p仍然持有对堆上这块内存的引用,使得这块内存不会立即成为悬空指针。

    4. 因此,代码中free(p)是必要的,它确保了堆上分配的内存被正确释放,防止了内存泄漏。如果不调用free(p),程序结束时这部分内存虽然对当前进程不可访问,但依然占用系统资源,可能导致长期运行的应用程序内存消耗增加。

    总结,尽管a作为局部变量在函数结束时失效,但通过它分配并返回的堆内存地址被p接收,保持了对这块内存的访问权限,直到free(p)被调用来释放这块堆空间。这是管理C语言程序内存的关键机制之一。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 4月30日

悬赏问题

  • ¥20 设计一个二极管稳压值检测电路
  • ¥15 内网办公电脑进行向日葵
  • ¥15 如何输入双曲线的参数a然后画出双曲线?我输入处理函数加上后就没有用了,不知道怎么回事去掉后双曲线可以画出来
  • ¥50 WPF Lidgren.Network.Core2连接问题
  • ¥15 soildworks装配体的尺寸问题
  • ¥100 有偿寻云闪付SDK转URL技术
  • ¥30 基于信创PC发布的QT应用如何跨用户启动后输入中文
  • ¥20 非root手机,如何精准控制手机流量消耗的大小,如20M
  • ¥15 远程安装一下vasp
  • ¥15 自己做的代码上传图片时,报错