C++进程空间堆栈的图解与代码注释

本文介绍了C++中进程空间的结构,重点解析了堆和栈的运作方式。栈在函数调用时自动完成局部变量的入栈和出栈操作,而堆则提供灵活的内存分配,解决了固定大小数组可能导致的问题。通过举例说明了堆内存的使用场景和优点,指出堆在C++实例化对象时的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C与C++的进程空间化成了好多的区间,这些区间存储的内容并不同。下面利用代码进行解析。
这里写图片描述
上图是进程空间的结构。
(注):很多书上讲到堆是向上增,栈是向下降。这种说话很不明确,因为不同的书上有不同的画法。准确的说是堆向高地址增长,栈向低地址增长。
一段C或C++的代码,具体的变量到底怎么存储如下:

#include<stdio.h>
#include<malloc.h>

int a = 1;//已初始化数据全局变量
int b;//未初始化数据
void main()
{
    int b; //局部变量,注意,只是局部变量,因为在函数中定义。存在栈中。
    char[] = "abc"; //局部变量 存在栈中。
    char *p1; //局部指针变量,存在栈中。
    char *p2 = "12345"; //12345属于常量,在常量区内存储。其中常量属于已初始化数据,在data去,因为常量可以赋给任何变量。
    static int C = 0;//静态变量,在已初始化区
    p1 = (char*)malloc(sizeof(char));
    p2 = (int*)malloc(sizeof(int));
    //上面变量p1与p2在栈中,利用malloc申请的区域在堆中
    free(p1);
    free(p2);
    //free函数会清除掉堆中的函数。
}

(一),入栈与出栈
栈的利用系统都会自动完成顺序也很明确,当从main函数入口时。局部变量依次入栈,函数调用结束再依次出栈,因此顺序很明确。
(二),堆空间的使用
(1),为何要用堆的空间,先看下面的例子:读入一个含n个整数的数组。代码如下:

#include"csapp.h"
#define MAIX 100

int array[MAIX];// 此数组存在初始化区;
int main()
{
    int i n;
    scanf("%d",&n);
    if (n > MAIX)
    {
        app_error("too big");
    }
    for(i = 0;i < n;i++)
    {
        scanf("%d",&array[i]);
    }
    exit(0);
}

上面的代码没有任何的毛病,但问题在维护上。因为只能接受100大小的数组,大的话会报错,当然可以把数组设的很大,但是会造成内存的浪费和维护的麻烦。甚至来说,如果数组太大,会造成内存泄露。
(2),堆的好处
上面的代码存在初始化数据区显然不合适,这就引出堆的好处,要多少内存给多少,并且能够及时回收。

#include"csapp.h"

int main()
{
    int i n *array;  //array这个指针在栈里存着
    scanf("%d",&n);
    array = (int*)malloc(n*sizeof(int));//array指针指向堆区的一个地址,大小为自己申请。
    for(i = 0;i < n;i++)
    {
        scanf("%d",&array[i]);
    }
    free(array);//不会造成内存浪费
    exit(0);
}

注:(1)向堆申请内存的方式在C++的实例化对象的部分会更为显著。
(2)堆栈的用法与细节比这要更为的复杂,此文章只是简要的概述大致过程。
(3)希望有理解错的地方各位及时指正,谢谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值