C/C++程序运行的五种内存分区

news/2024/10/31 5:25:32/

1.简介

在C/C++程序运行时,所使用的内存分为代码区(Code)堆区(Heap)栈区(Stack)全局/静态存储区(static)常量存储区(const) 五个分区。注意此处的堆和栈并不是指数据结构

从网上找的图,侵删

2.详解

(1)代码区

这个区域存放程序包含的所有函数体的二进制代码

(2)堆区

由用户代码分配/释放,下面的语句将会分配堆上的存储空间:

char *p = (char *)malloc(10); //分配一段10字节的存储空间

(3)栈区

由系统自动分配的空间,用户代码无法控制,用于存放局部变量,下面的代码片段创建了三个存储在栈上的不同类型的变量(或数组),对应三块大小不同的存储空间:

void main()
{
int a=10;
float c[5];
char *b;
}

栈区是向下存储的,每次分配的地址越来越小,堆区是向上存储的(顾名思义,堆起来),每次分配的地址越来越大

(4)全局/静态存储区

在所有函数外部定义的全局变量,以及通过static修饰的任意位置的变量都存储在该区域,下面的示例创建了3个存储在全局/静态存储区的变量

int a=4;
void punc() {
static int b=5;
}
void main() {
punc();
static char c=‘c’;
}

上面的例子中a,b,c三个变量都存储在全局/静态存储区
下面的示例有助于我们理解全局/静态存储区和栈区变量的区别,以及 static关键字的作用

 #include <stdio.h>
void test1()
{static int b=1;printf("static b = %d\n",b++);
}
void test2()
{int b=1;printf("b = %d\n",b++);
}
void main()
{for(int i=1;i<=3;i++){   test1();test2();}
}

运行结果:

static b = 1
b = 1
static b = 2
b = 1
static b = 3
b = 1

从上面的例子我们不难发现:
1.static关键字修饰的静态局部变量的声明语句只会在第一次执行的时候初始化,之后即使反复执行也不会重新初始化
2.普通的存储在栈上的局部变量每次执行声明/赋值语句都会进行一次初始化
3. static关键字修饰的变量仍然是局部变量,无法从外部调用,也不会和其他作用域的同名变量起冲突

(5)常量存储区

通过#defineconst定义的常量, 源代码中以指针形式定义的字符串,都存储在常量存储区。和主程序的生命周期相同,而且他们的值在编译时已经确定,一旦创建就无法更改(非正常手段除外)。
下面的例子展示了哪些数据会存储在常量存储区

#define PI 3.14
const int P=3
void main()
{
char *s=“hello”;
}

上面声明的变量都存储在常量存储区,其中char指针s本身存储在栈上,他指向的值存放在常量存储区。一个很简单的证据就是*s不可被二次赋值:

附:#defineconst的区别:

(1)就起作用的阶段而言: #define是在编译的预处理阶段起作用,而const是在 编译、运行的时候起作用。
(2)就起作用的方式而言:
#define只是简单的字符串替换,没有类型检查。而const有对应的数据类型,是要进行判断的,可以避免一些低级的错误。
(3)就存储方式而言:#define只是进行展开,有多少地方使用,就替换多少次,它定义的宏常量在内存中有若干个备份;const定义的只读变量在程序运行过程中只有一份备份。
(4)从代码调试的方便程度而言: const常量可以进行调试的,define是不能进行调试的,因为在预编译阶段就已经替换掉了。
const优点: (1)const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误。
(2)有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。
(3)const可节省空间,避免不必要的内存分配,提高效率

引用自: const与#define相比,区别和优点超详解总结!


http://www.ppmy.cn/news/434307.html

相关文章

C语言内存

1.程序中内存从哪里来 1.1、程序执行需要内存支持 对程序来说&#xff0c;内存就是程序的立足之地&#xff08;程序是被放在内存中运行的&#xff09;&#xff1b;程序运行时需要内存来存储一些临时变量。 1.2、内存管理最终是由操作系统完成的 (1)内存本身在物理上是一个硬件…

程序载入内存,程序运行

如果你的电脑上安装了QQ&#xff0c;你希望和好友聊天&#xff0c;会双击QQ图标&#xff0c;打开QQ软件&#xff0c;输入账号和密码&#xff0c;然后登录就可以了。 那么&#xff0c;QQ是怎么运行起来的呢&#xff1f; 首先&#xff0c;有一点你要明确&#xff0c;你安装的QQ…

程序运行时内存如何分配的

之前有很多人将 Java 的内存分为堆内存&#xff08;heap&#xff09;和栈内存&#xff08;Stack&#xff09;&#xff0c;这种划分方式在一定程度上体现了这两块区域是 Java 工程师最关注的内存区域。但是其实这种划分方式并不完全准确。 Java 的内存区域划分实际上远比这复杂…

iPhone上的CPU架构,核数以及运行内存

机型CPU架构CPU名CPU位数CPU核数运行内存iPhone 5ARMv7sA632bit双核1GiPhone 5cARMV7sA632bit双核1GiPhone 5sARM64A764bit双核1GiPhone 6ARM64A864bit双核1GiPhone 6sARM64A964bit双核2GiPhone 7ARM64A1064bit四核2GiPhone 7sARM64A1064bit四核3GiPhone 8ARM64A1164bit六核2Gi…

程序运行时内存的各种数据段

文章目录 1.bss段2.data段3.rodata段4.text段5.stack段6.heap段 1.bss段 该段用来存放没有被初始化或初始化为0的全局变量&#xff0c;因为是全局变量&#xff0c;所以在程序运行的整个生命周期内都存在于内存中。 有趣的是这个段中的变量只占用程序运行时的内存空间&#xf…

6S模型运行 1

6S模型准备 最近要用6S模型进行大气模拟&#xff0c;以此记录下整个过程 安装 参考博客-6SV2.1模型编译心得&#xff08;WINDOWS7&#xff09; 原文链接&#xff1a;https://blog.csdn.net/u010472858/article/details/84345773 1.WINDOWS系统需要下载UNIX工具&#xff0c;…

C++程序运行时的内存与地址

本文全部内容&#xff0c;以SSD6的Exercise1为示例。 代码如下图。 #include <stdio.h> #include <stdlib.h> #include <iostream>int prologue [] {0x5920453A, 0x54756F0A, 0x6F6F470A, 0x21643A6F,0x6E617920, 0x680A6474, 0x6F697661, 0x20646E69,0x6…

c++程序在运行时内存分配

一个c程序运行的时候&#xff0c;会规划如下内存区域 1、栈stack&#xff0c;存放函数的参数值&#xff0c;局部变量的值等&#xff0c;由系统自动分配&#xff0c;自动释放。先进后出&#xff0c;内存是连续的。 2、堆heap&#xff0c;由程序员分配和释放&#xff0c;若频繁…