当前位置: 首页 > news >正文

【C++ 面试 - 内存管理】每日 3 题(一)

✍个人博客:Pandaconda-CSDN博客

📣专栏地址:http://t.csdnimg.cn/fYaBd

📚专栏简介:在这个专栏中,我将会分享 C++ 面试中常见的面试题给大家~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪

1. 简要说明 C++ 的内存分区

C++ 中的内存分区,分别是堆、栈、自由存储区、全局/静态存储区、常量存储区和代码区。

  

:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

:就是那些由 malloc 等分配的内存块,和堆是十分相似的,不过是用 free 来结束自己的生命(new 也可以在堆上分配内存)

自由存储区:就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。

全局/静态存储区:全局变量和静态变量被分配到同一块内存中,在以前的 C 语言中,全局变量和静态变量又分为初始化的和未初始化的,在 C++ 里面没有这个区分了,它们共同占用同一块内存区,在该区定义的变量若没有初始化,则会被自动初始化,例如 int 型变量自动初始为 0。

常量存储区:这是一块比较特殊的存储区,这里面存放的是常量,不允许修改。

代码区:存放函数体的二进制代码。

2. C++ 中类的数据成员和成员函数内存分布情况

C++ 类是由结构体发展得来的,所以他们的成员变量(C 语言的结构体只有成员变量)的内存分配机制是一样的。下面我们以类来说明问题,如果类的问题通了,结构体也也就没问题啦。类分为成员变量和成员函数,我们先来讨论成员变量。

一个类对象的地址就是类所包含的这一片内存空间的首地址,这个首地址也就对应具体某一个成员变量的地址。(在定义类对象的同时这些成员变量也就被定义了),举个例子:

#include <iostream>
using namespace std;class Person
{
public:Person(){this->age = 23;}void printAge(){cout << this->age <<endl;}~Person(){}
public:int age;
};int main()
{Person p;cout << "对象地址:"<< &p <<endl;cout << "age地址:"<< &(p.age) <<endl;cout << "对象大小:"<< sizeof(p) <<endl;cout << "age大小:"<< sizeof(p.age) <<endl;return 0;
}
//输出结果
//对象地址:0x7fffec0f15a8
//age地址:0x7fffec0f15a8
//对象大小:4
//age大小:4

从代码运行结果来看,对象的大小和对象中数据成员的大小是一致的,也就是说,成员函数不占用对象的内存。这是因为所有的函数都是存放在代码区的,不管是全局函数,还是成员函数。

要是成员函数占用类的对象空间,那么将是多么可怕的事情:定义一次类对象就有成员函数占用一段空间。

我们再来补充一下静态成员函数的存放问题:静态成员函数与一般成员函数的唯一区别就是没有 this 指针,因此不能访问非静态数据成员。

就像我前面提到的,所有函数都存放在代码区,静态函数也不例外。所以有人一看到 static 这个单词就主观的认为是存放在全局数据区,那是不对的。

3. 介绍一下内存对齐

  1. 自然对齐边界:对于基本数据类型,其自然对齐边界通常为其大小。例如,char 型的自然对齐边界为 1 字节, short 为 2 字节, int 和 float 为 4 字节, double 和 64 位指针为 8 字节。具体数值可能因编译器和平台而异。

  2. 结构体对齐:结构体内部的每个成员都根据其自然对齐边界进行对齐。也就是可能在成员之间插入填充字节。结构体本身的总大小也会根据其最大对齐边界的成员进行对齐(比如结构体成员包含的最长类型为 int 类型,那么整个结构体要按照 4 的倍数对齐),以便在数组中正确对齐。

  3. 联合体对齐:联合体的对齐边界取决于其最大对齐边界的成员。联合体的大小等于其最大大小的成员,因为联合体的所有成员共享相同的内存空间。

  4. 编译器指令:可以使用编译器指令 (如 #pragma pack ) 更改默认的对齐规则。这个命令是全局生效的。这可以用于减小数据结构的大小,但可能会降低访问性能。

  5. 对齐属性:在 C++11 及更高版本中,可以使用 alignas 关键字为数据结构或变量指定对齐要求。这个命令是对某个类型或者对象生效的。例如, alignas(16) int x; 将确保 x 的地址是 16 的倍数。

  6. 动态内存分配:大多数内存分配函数 (如 malloc 和 new ) 会自动分配足够对齐的内存,以满足任何数据类型的对齐要求。


http://www.mrgr.cn/news/10827.html

相关文章:

  • tortoisegit突然停止工作
  • docker-harbor私有仓库部署和管理
  • Ps:首选项 - 工具
  • 【Midjourney】Midjourney全面开放网站版,所有用户每天可免费生成25次
  • LeetCode Hot100:283、移动零
  • Tomcat的配置文件中有哪些关键的配置项,它们分别有什么作用?
  • 【html+css 绚丽Loading】 000018 五行伸缩剑
  • Llama 4B剪枝蒸馏实战
  • 协议汇总 TCP、UDP、Http、Socket、Web Scoket、Web Service、WCF、API
  • 下载B站视频作为PPT素材
  • 神经网络微调技术全解(03)-Prompt Tuning全面解析
  • 线性代数 第一讲 行列式_行列式定义_性质_计算_题型总结
  • 苹果机器人计划:能否成为智能家居的破局者?
  • C++_11特性
  • Scrum 敏捷模型、软件测试
  • 云存储服务器租用的好处有哪些?
  • 通过$r访问应用资源是否支持嵌套形式
  • Git在IDEA中的集成操作(附步骤图)
  • leetcode54 螺旋矩阵
  • 有一种“穷人性格”,大事拎不清,小事算太精