2021-11-06 C++程序内存模型-内存四区

2024-06-10 13:58

本文主要是介绍2021-11-06 C++程序内存模型-内存四区,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

C++程序在执行时,将内存大方向划分为4个区域:

全局区,代码区,栈区,堆区

1. 代码区和全局区

在程序编译后,生成了exe可执行程序,未执行该程序前分为两个区域(代码区和全局区

1.1 代码区

代码区:存放函数体的二进制代码,由操作系统进行管理
存放CPU执行的机器指令。
代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码即可。
代码区是只读的,使其只读的原因是防止程序意外地修改了它的指令

1.2 全局区

全局区:存放全局变量和静态变量以及常量
全局变量和静态变量存放在此
全局区还包含了常量区,字符串常量和其他常量也存放在此处
该区域的数据在程序结束后由操作系统释放

#include<iostream>
using namespace std;/*全局变量*/
int c = 10;
int d = 10;/*const修饰全局常量*/
const int g = 10;
const int h = 10;int main()
{/*全局区*//*静态变量  在普通变量前加static,属于静态变量*/static int e = 10;static int f = 10;/*创建普通局部变量*/int a = 10;int b = 10;/*const修饰局部常量*/const int s = 10;const int m = 10;/*常量 1.字符串常量 */cout << "字符串常量的地址为:" << (int)&"hello word" << endl;cout << endl;cout << "局部变量a的地址为:" << (int)&a << endl;cout << "局部变量b的地址为:" << (int)&b << endl;cout << endl;cout << "全局变量c的地址为:" << (int)&c << endl;cout << "全局变量d的地址为:" << (int)&d << endl;cout << endl;cout << "静态变量e的地址为:" << (int)&e << endl;cout << "静态变量f的地址为:" << (int)&f << endl;cout << endl;cout << "const修饰的全局常量g的地址为:" << (int)&g << endl;cout << "const修饰的全局常量h的地址为:" << (int)&h << endl;cout << endl;cout << "const修饰的局部常量s的地址为:" << (int)&s << endl;cout << "const修饰的局部常量m的地址为:" << (int)&m << endl;cout << endl;system("pause");return 0;
}

在这里插入图片描述

总结:

C++中在程序运行前分为全局区和代码区
代码区特点是共享和只读
全局区中存放全局变量,静态变量,常量
常量区中存放const修饰的全局常量和字符串常量

2. 栈区和堆区

2.1 栈区

由编译器自动分配释放,存放函数的参数值,局部变量等。

#include<iostream>
using namespace std;/*
栈区数据的注意事项--不要返回局部变量地址
栈区的数据由编译器管理开辟和释放
*/
int * fun()
{int a = 10; //局部变量,存放在栈区,栈区的数据在函数执行完后自动释放return &a; //返回局部变量的地址
}int main()
{int * p = fun(); //接收fun函数的返回值cout << * p << endl;  //第一次可以打印正确的数字,因为编译器做了保留cout << * p << endl; //第二次这个数据就不再保留了,此块内存已被释放system("pause");return 0;
}

2.2 堆区

由程序员分配和释放,若程序员不释放,程序结束时由操作系统收回,C++中主要利用new在堆区开辟内存

#include<iostream>
using namespace std;/*
栈区数据的注意事项--不要返回局部变量地址
栈区的数据由编译器管理开辟和释放
*/
int * fun() //形参数据也会放在栈区
{//利用new关键字,可以将数据开辟到堆区//指针本质是局部变量 ,放在栈上。指针保存的数据放在堆区int* p = new int(10);return p;
}int main()
{//在堆区开辟数据int * p = fun(); //接收fun函数的返回值cout << * p << endl;  system("pause");return 0;
}

3. new操作符

C++中利用new操作符在堆区开辟数据,堆区开辟的数据,由程序员受到开辟,手动释放,释放利用操作符delete。
利用new创建的数据,会返回该数据对应的类型的指针。

#include<iostream>
using namespace std;/*new的基本语法*/
int* func()
{/*在堆区创建整形数据new返回的是该数据类型的指针*/int* p = new int(10);return p;
}void text01()
{int* p = func();cout << *p << endl;//堆区数据由程序员管理释放delete p; 
//	cout << *p << endl;   内存已经释放,再次访问就是非法操作,会报错
}void text02()
{/*创建10个整形数据的数组,在堆区*/int* arr = new int[10];for (int i = 0; i < 10; i++){arr[i] = i + 100;}for (int i = 0; i < 10; i++){cout << arr[i] << endl;}//释放堆区数组//释放数组的时候,要加[]才可以delete[]arr;
}int main()
{//text01();text02();system("pause");return 0;
}

总结

不同区域存放的数据,赋予不同的生命周期,给我们更大的灵活编程。

这篇关于2021-11-06 C++程序内存模型-内存四区的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1048353

相关文章

C++右移运算符的一个小坑及解决

《C++右移运算符的一个小坑及解决》文章指出右移运算符处理负数时左侧补1导致死循环,与除法行为不同,强调需注意补码机制以正确统计二进制1的个数... 目录我遇到了这么一个www.chinasem.cn函数由此可以看到也很好理解总结我遇到了这么一个函数template<typename T>unsigned

python获取指定名字的程序的文件路径的两种方法

《python获取指定名字的程序的文件路径的两种方法》本文主要介绍了python获取指定名字的程序的文件路径的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 最近在做项目,需要用到给定一个程序名字就可以自动获取到这个程序在Windows系统下的绝对路径,以下

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

Redis实现高效内存管理的示例代码

《Redis实现高效内存管理的示例代码》Redis内存管理是其核心功能之一,为了高效地利用内存,Redis采用了多种技术和策略,如优化的数据结构、内存分配策略、内存回收、数据压缩等,下面就来详细的介绍... 目录1. 内存分配策略jemalloc 的使用2. 数据压缩和编码ziplist示例代码3. 优化的

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

Python内存优化的实战技巧分享

《Python内存优化的实战技巧分享》Python作为一门解释型语言,虽然在开发效率上有着显著优势,但在执行效率方面往往被诟病,然而,通过合理的内存优化策略,我们可以让Python程序的运行速度提升3... 目录前言python内存管理机制引用计数机制垃圾回收机制内存泄漏的常见原因1. 循环引用2. 全局变

C++ STL-string类底层实现过程

《C++STL-string类底层实现过程》本文实现了一个简易的string类,涵盖动态数组存储、深拷贝机制、迭代器支持、容量调整、字符串修改、运算符重载等功能,模拟标准string核心特性,重点强... 目录实现框架一、默认成员函数1.默认构造函数2.构造函数3.拷贝构造函数(重点)4.赋值运算符重载函数

C++ vector越界问题的完整解决方案

《C++vector越界问题的完整解决方案》在C++开发中,std::vector作为最常用的动态数组容器,其便捷性与性能优势使其成为处理可变长度数据的首选,然而,数组越界访问始终是威胁程序稳定性的... 目录引言一、vector越界的底层原理与危害1.1 越界访问的本质原因1.2 越界访问的实际危害二、基

基于Python编写自动化邮件发送程序(进阶版)

《基于Python编写自动化邮件发送程序(进阶版)》在数字化时代,自动化邮件发送功能已成为企业和个人提升工作效率的重要工具,本文将使用Python编写一个简单的自动化邮件发送程序,希望对大家有所帮助... 目录理解SMTP协议基础配置开发环境构建邮件发送函数核心逻辑实现完整发送流程添加附件支持功能实现htm

C#控制台程序同步调用WebApi实现方式

《C#控制台程序同步调用WebApi实现方式》控制台程序作为Job时,需同步调用WebApi以确保获取返回结果后执行后续操作,否则会引发TaskCanceledException异常,同步处理可避免异... 目录同步调用WebApi方法Cls001类里面的写法总结控制台程序一般当作Job使用,有时候需要控制