什么是数据区域
What is data area?
在C++存储类说明符 static 从数据区域分配内存。"数据区域"是什么意思?
熟悉术语"数据区域",但内存通常分为"代码部分"和"数据部分"。代码驻留在前者中,数据驻留在后者中。我想这就是这里的意思。
传统上,两者之间没有区别。但是,许多现代操作系统可以禁止在数据段中执行代码(前提是 CPU 支持这种区别)。这有时以"NX 标志"为口号,如"不执行",可以有效防止某些恶意代码注入的情况。
/编辑:请注意,C++标准没有提到"数据区域"。
除了 Konrad 所说的之外,将变量声明为静态基本上意味着它的内存在加载时与程序一起分配,而不是在堆或堆栈上。 从历史上看,在关键应用程序中仅使用静态变量意味着应用程序的内存占用量在运行时不会更改,因此由于资源限制而失败的可能性较小。 不知道现代操作系统是否仍然如此。
如果让编译器生成映射文件作为其输出的一部分,则可以查看所有各个部分(包括数据)中的内容。
区域的名称因平台、编译器和链接器而异。
一般来说,有:
- 程序文本:可执行代码空间。
- 常量:不可执行的常量。
- 堆栈:堆栈。
- bss:广义的C/C++术语中的"静态"。 "由符号启动的块"
- 数据:未初始化的全局变量
- 堆:运行时分配的存储。
在这种情况下,有问题的文档使用名称"数据区域"来表示传统上称为 bss 段的内容。
在 C 术语中,存储类说明符"static"表示在程序的生存期内存在的内存,并且初始化为初始化器的零或值。 在示例中:
static int s_value_one;
static int s_value_two = 123;
s_value_one 的值保证为零,s_value_type 的值在 main() 中第一个语句的位置为 123。 这如何成为现实是一个实现问题。
康拉德说的话。
我想补充一点,如果将数据放置在代码部分,仍然有 CPU 无法读取数据,反之亦然。这些在几十年前更为常见,但它们仍然存在于嵌入式世界中。
简而言之,链接器只是将相同种类的符号组合在一起。在PC上,您通常拥有的不仅仅是简单的代码和数据区域。您将找到未初始化数据,只读数据和其他与操作系统相关的内容的区域。
通过谷歌搜索,我在这里找到了有关这些主题的更多信息:
- http://www.informit.com/articles/article.aspx?p=31783&seqNum=4
- http://www.codeguru.com/cpp/tic/tic0111.shtml
数据可能会在很多地方结束。通常,局部变量是在堆栈上分配的,您可以使用 malloc(或 'new' 的默认版本)在堆上分配内容。但是,静态数据通常在程序启动时分配,并且可能最终位于任何地方 - 确切地取决于编译器,操作系统和可执行格式。
中有很多信息。
可执行文件在其物理文件中存储了许多类型/类的数据。
例如,是
- 可执行代码指令
- 资源
- 依赖关系信息(此二进制文件所依赖的 dll)
- 从此二进制文件导出的符号
等
需要某种组织方式
所有这些信息都以.exe文件格式提供,以便操作系统可以轻松找到所有信息并加载可执行文件并使事情正常工作。为此,在Windows世界中使用了一种称为PE(可移植可执行文件)的通用二进制格式(当然由M$创建)。我刚刚列出的所有信息(以及更多信息)都在二进制文件的不同部分中进行了详细描述。
.数据部分
其中一个部分是 .data 部分。 .data 部分包含所有初始化的全局和静态数据,而 .bss 部分包含未初始化的全局数据。
为什么需要为全局变量单独设置一个部分?
好吧,全局的行为类似于全局,因为它是在程序生命周期内存区域中创建的,而不是像堆栈那样可能被覆盖/重用的临时数据结构。(如普通自变量)。
编译器
因此,这些变量需要在堆中的某个永久地址中分配,不幸的是,在编译时无法知道。因此,编译器将所有全局变量和静态变量都放在 .data/.bss 部分中,引用这些变量的指令引用 .data/.bss 中的这些相对永久的地址。
连接
当链接器在现实世界中加载可执行文件时,它会决定必须放置这些部分的位置,并为这些临时地址创建 FIX UP,以便引用全局变量的指令引用程序内存中现在真实的虚拟地址。
现在您知道 .data 部分/区域是什么,以及为什么需要在该区域中为全局变量分配一些空间,以及这如何实时帮助程序。谷歌搜索PE格式和链接器和.data部分等会得到链接。
我认为"数据区域"指的是堆,而局部变量通常位于堆栈上。
或者这意味着为此变量分配的内存位于可执行文件的 .data 部分中,但这将特定于 Windows 和 PE 格式。
- 防止主数据类型C++的隐式转换
- 用于访问容器<T>数据成员的正确 API
- 嵌套在类中时无法设置成员数据
- 使用流处理接收到的数据
- 内存映射区域初始数据
- 为 pcl::P ointCloud 数据指定一个区域并获取可用点数
- 滚动区域数据居中对齐 希望将其更改为左对齐
- 获得有关硬盘扇区中原始数据更改的通知-文件更改通知
- 在不复制数据的情况下将OpenCV Mat发送到MATLAB工作区的方法
- WinInet InternetReadFile返回0x8007007a(传递给系统调用的数据区域太小)
- C++将数据写入随机HDD扇区
- 将较小的数据块合并到一个较大的内存区中
- 获取二进制文件的数据和代码区域的大小
- Lua注册表与轻用户数据和引用之间的区别是什么?
- 如何区分类成员函数的声明和数据成员的声明
- ReadFile FILE_FLAG_NO_BUFFERING如何读取两个扇区之间的数据
- 重新定义数据区域以便更快地访问
- 代码是否被视为可移植可执行文件格式中的初始化数据,初始化数据和单元化数据之间的确切区别是什么
- 如何在CD或DVD上获得扇区的准确位置和角度(数据位置测量)
- 什么是数据区域