c - 为什么我不能在 BSS 中获取静态变量?

标签 c gcc memory

据我所知,如果设置了 -fzero-initialized-in-bss,则未明确初始化的静态变量(并且对于 GCC,即使是那些明确初始化为零的变量,默认情况下就是这种情况)通常存储在 BSS 段中。然而,当我尝试检查该行为时,这些变量似乎存储在通用数据部分(带有初始化的全局变量)中。如果我编译(使用 -O0 作为衡量标准)并运行:

#include <stdio.h>
#include <stdlib.h>

extern char etext, edata, end;

int i = 42;

int main(int argc, char* argv[])
{
        static int j;
        printf ("end of program (etext) = %10p\n",&etext);
        printf ("end of initialized data (edata) = %10p\n",&end);
        printf ("end of uninitialized data (end) = %10p\n",&end);
        printf ("=====\n");
        printf ("Value of i (initialized global) : %d\n",i);
        printf ("Address of i : %10p\n",&i);
        printf ("Value of j (static with no explicit initialization) : %d\n",j);
        printf ("Address of i : %10p\n",&j);
        return 0;
}

我得到输出:

end of program (etext) =   0x40067d
end of initialized data (edata) =   0x600af0
end of uninitialized data (end) =   0x600af0
=====
Value of i (initialized global) : 42
Address of i :   0x600ae0
Value of j (static with no explicit initialization) : 0
Address of i :   0x600ae8

所以ij存储在连续的内存地址,在&etext&edata之间,也就是常规数据部分。此外,如果我理解正确的话,&edata == &end 似乎意味着 BSS 是空的。

现在我意识到编译器把哪个变量放在哪里是一个实现选择,它产生的结果是正确的。但我只是想知道为什么我会出现这种行为,以及是否有办法告诉 gcc 明确地将此类变量放入 BSS(我在手册中没有看到任何明显的解决方案)。

最佳答案

您的代码有错误。您为 edata 和 end 都打印了 end 的地址,因此您当然假设 edata == end,但事实并非如此。

当我修复您的代码并运行它时,我得到:

end of program (etext) = 0x8048578
end of initialized data (edata) = 0x804988c
end of uninitialized data (end) = 0x8049894

Value of i (initialized global) : 42
Address of i : 0x8049888
Value of j (static with no explicit initialization) : 0
Address of j : 0x8049890

很明显,j 位于 edata 和 end 之间的区域,而不是与 i 位于同一位置。

(gcc 5.2.1 20150911(Debian 5.2.1-17),32 位)

关于c - 为什么我不能在 BSS 中获取静态变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33167982/

相关文章:

ios - NSFileManager 的 moveItemAtPath 是否为 :toPath:error method load the file being moved into memory?

c - 如何找到C语言中1最多的区域?

c - 共享库编译 gcc

c - 在 x64 处理器上字对齐加载是否比非对齐加载更快?

c++ - g++ 在 osx 上使用 -O3 优化错误

macos - 使用 i386 arch 而非 x86_64 在 OSX 上构建 libFLAC

c - 何时为 C 中的结构和 "create"函数分配内存

windows - 帮助了解 Windows 内存 - "Working Set"

c - 反转链表并打印结果

c - Valgrind 提示 "Invalid write of size 8"