什么是数据区?
在C ++中,存储类说明符static从数据区域分配内存。 "数据区域"是什么意思?
解决方案
我对数据区域一词并不熟悉,但内存通常分为代码部分和数据部分。代码驻留在前者中,数据驻留在后者中。我想这就是这里的意思。
传统上,两者之间没有区别。但是,许多现代操作系统都可以禁止在数据段中执行代码(前提是CPU支持此区分)。有时这会被NX标志的流行用语,因为它不执行,并且可以有效地防止恶意代码注入的某些情况。
/ EDIT:请注意,C ++标准未提及数据区域。
康拉德说了什么。
我想补充一点,如果将它们放在代码部分中,仍然有一些CPU无法读取数据,反之亦然。这些已经在几十年前变得更加普遍,但是在嵌入式世界中它们仍然存在。
简而言之,链接器仅将相同种类的符号分组在一起。在PC上,我们通常不仅拥有简单的代码和数据区域。我们会发现未初始化数据,只读数据和其他与OS相关的内容的区域。
通过很少的搜索,我在这里找到了有关这些主题的更多信息:
- http://www.informit.com/articles/article.aspx?p=31783&seqNum=4
- http://www.codeguru.com/cpp/tic/tic0111.shtml
我认为"数据区域"是指堆,而局部变量通常位于堆栈上。
或者这意味着为此变量分配的内存位于可执行文件的.data节中,但这将特定于Windows和PE格式。
数据可能在很多地方都存在。通常,局部变量是在堆栈上分配的,我们可以使用malloc(或者默认版本的" new")在堆上分配内容。但是,静态数据通常是在程序启动时分配的,并且可能会在任何地方结束,具体取决于编译器,操作系统和可执行格式。
区域的名称因平台,编译器和链接器而异。
通常,有:
- 程序文本:可执行代码空间。
- 常量:不可执行的常量。
- 堆栈:堆栈。
- bss:用C / C ++术语广义地讲是"静态"。 "由符号开始的块"
- 数据:未初始化的全局变量
- 堆:在运行时分配的存储。
在这种情况下,相关文档将名称"数据区域"用于传统上称为bss段的地方。
用C术语来说,存储类说明符"静态"是指在程序生命周期内存在的内存,并已初始化为零或者初始化程序的值。在示例中:
static int s_value_one; static int s_value_two = 123;
保证在main()中第一条语句的点s_value_one的值为零,并且s_value_type的值为123. 如何实现是一个实现问题。
除了Konrad所说的之外,将变量声明为静态变量基本上意味着在程序加载时将其内存分配给程序,而不是在堆或者堆栈上分配。从历史上看,在关键应用程序中仅使用静态变量意味着该应用程序的内存占用量不会在运行时更改,因此,由于资源限制而导致失败的可能性较小。不知道现代操作系统是否仍然如此。
如果让编译器在其输出中生成映射文件,则可以查看所有各个部分(包括数据)中的内容。
可执行文件中包含很多信息。
可执行文件在其物理文件中存储有许多类型/类型的数据。
例如是
- 可执行代码指令
- 资源
- 依赖关系信息(此二进制文件依赖哪个dll)
- 从此二进制文件导出的符号
等等
需要某种方式来组织
所有这些信息都位于.exe文件格式内,因此操作系统可以轻松找到所有信息并加载可执行文件,并使一切正常运行。为此,在Windows世界中使用了一种称为PE(便携式可执行文件)的通用二进制格式(由M $课程创建)。我刚刚列出的所有信息(以及更多信息)都在二进制文件的不同部分中进行了详细说明。
.data部分
.data部分就是这样的一个部分。 .data节包含所有初始化的全局和静态数据,而.bss节包含未初始化的全局数据。
为什么对全局变量需要一个单独的部分?
好的,全局行为就像全局一样,因为它是在程序生命周期内存在的内存区域中创建的,而不是像栈那样的临时数据结构,它可能会被覆盖/重用。 (如普通的自动变量)。
编译器
因此,需要在堆中的某些永久地址中分配这些变量,不幸的是,在编译时无法知道这些变量。因此,编译器将所有全局变量和静态变量都放在此.data / .bss节中,引用这些变量的指令在.data / .bss中引用了这些相对永久的地址。
连结器
链接器在现实世界中加载可执行文件时,它将决定这些节的放置位置,并为这些临时地址创建FIX UP,以便引用全局变量的指令引用程序存储器中当前的实际虚拟地址。
现在,我们知道什么是.data节/区域,以及为什么需要在该区域中分配全局变量,以及这如何实时地帮助程序。谷歌搜索PE格式和链接器以及.data部分等将为我们提供链接。