常量variables存储在C中哪里?
我想知道常量variables的存储位置。 在与全局variables相同的内存区域? 或在堆栈上?
他们如何存储是一个实现细节(取决于编译器)。
例如,在GCC编译器中,在大多数机器上,只读variables,常量和跳转表被放置在文本部分。
根据特定处理器所遵循的数据分段,我们有五个分段:
- 代码段 – 只存储代码,ROM
- BSS(或由符号启动的块)段 – 存储初始化的全局variables和静态variables
- 堆栈段 – 存储所有的本地variables和其他有关函数返回地址等信息
- 堆段 – 所有dynamic分配发生在这里
- 数据段 – 存储未初始化的全局variables和静态variables
请注意,BSS和数据段之间的区别在于前一个存储初始化了全局variables和静态variables,而后者存储了未初始化的variables。
现在,当我必须告诉数据存储在哪里时,为什么我要谈论数据分段……这是有原因的…
每个段都有一个写保护区域,其中存储了所有的常量。
例如,
如果我有一个const int是局部variables,那么它被存储在堆栈段的写保护区域中。 如果我有一个全局的初始化const var,那么它存储在BSS,如果我有一个未初始化的常量variables,那么它存储在数据段…
总而言之,“const”只是一个QUALIFIER数据,这意味着编译器首先必须决定哪个段必须被存储,然后如果该variables是一个const,那么它就有资格存储在写保护区那个特定的部分。
我希望这会澄清大部分的误解…. 🙂
任何进一步的意见,欢迎… 🙂
考虑下面的代码:
const int i = 0; static const int k = 99; int function(void) { const int j = 37; totherfunc(&j); totherfunc(&i); //totherfunc(&k); return(j+3); }
通常, i
可以存储在文本段(它是一个固定值的只读variables)。 如果它不在文本段中,它将被存储在全局variables旁边。 假定它被初始化为零,它可能在'bss'部分(通常分配零值variables)或'data'部分(通常分配初始化variables)。
如果编译器确信k
未被使用(可能是因为它是本地的单个文件),它可能根本不会出现在目标代码中。 如果对引用k
totherfunc()
的调用没有被注释掉,那么k
将不得不在某处被分配一个地址 – 它可能与i
在同一个段中。
常量(如果它是一个常量,它仍然是一个variables?) j
将最有可能出现在传统C实现的堆栈上。 (如果你在comp.std.c新闻组中询问,有人会提到标准没有说自动variables出现在堆栈上;幸运的是,SO不是comp.std.c!)
请注意,我强制variables出现,因为我通过引用传递它们 – 大概是一个函数期望指向一个常量整数。 如果地址从未被采用,那么j
和k
可以完全从代码中优化。 要删除i
,编译器必须知道整个程序的所有源代码 – 它可以在其他翻译单元(源文件)中访问,因此不能轻易删除。 如果程序沉迷于共享库的dynamic加载,那么就不会双倍使用 – 这些库中的一个可能依赖于全局variables。
(在风格上 – variablesi
和j
应该有更长,更有意义的名字,这只是一个例子!)
取决于编译器,系统function,编译时的configuration。
除非另行说明,否则gcc
在.text
节中放置只读常量。
通常它们存储在只读数据部分(而全局variables部分具有写权限)。 所以,试图通过地址来修改常量可能会导致访问冲突,也就是segfault。
但是这取决于你的硬件,操作系统和编译器。
这主要是一个受过教育的猜测,但我会说,常量通常存储在编译后程序的实际CPU指令中,作为立即数据。 换句话说,大多数指令都包含了从地址获取数据的空间,但是如果是常量,空间本身就可以保存数据。
不是因为性交
1)bss段存储非常量variables,显然是另一种types。
(I) large static and global and non constants and non initilaized variables it stored .BSS section. (II) second thing small static and global variables and non constants and non initilaized variables stored in .SBSS section this included in .BSS segment.
2)数据段是initlaizedvariables,它有3种types,
(I) large static and global and initlaized and non constants variables its stord in .DATA section. (II) small static and global and non constant and initilaized variables its stord in .SDATA1 sectiion. (III) small static and global and constant and initilaized OR non initilaized variables its stord in .SDATA2 sectiion.
我提到上面的小的和大的意味着依赖于编译器,例如小的方式<8字节和大的方式>大于8字节和相等的值。
但我的疑问是地方不变是哪里会stroe ??????
全局和常量是两个完全分离的关键字。 你可以有一个或其他,没有一个或两个。
那么你的variables存储在内存中的地方取决于configuration。 仔细阅读一下堆和堆 ,这会给你一些知识来问更多(如果我可以,更好,更具体)的问题。
一些常数甚至不会被存储。
考虑下面的代码: int x = foo(); x *= 2;
int x = foo(); x *= 2;
。 很有可能编译器会把乘法转换成x = x+x;
因为这减less了从内存加载数字2的需要。
它可能根本不存储。
考虑一下这样的代码:
#import<math.h>//import PI double toRadian(int degree){ return degree*PI*2/360.0; }
这使得程序员能够收集正在发生的事情,但编译器可以优化其中的一些,而大多数编译器通过在编译时对常量expression式进行评估,这意味着PI的值可能不会出现在结果程序中在所有。
正如你所知道的那样,在链接过程中,最终可执行文件的内存是由决定的。还有一个部分叫COMMON,在这个部分放置了来自不同input文件的通用符号。在.bss部分下。
它必须存储在文本段中,因为它是只读variables。 http://shirleyanengineer.blogspot.in/2017/05/memory-layout-of-process.html