全局数组分配 — 栈还是堆?

3

我将以下内容编译为Windows下的Visual Studio 2008。

当我声明一个全局数组如下:

//.cpp file

// on a global scale
// (i.e. outside any class definition)
MY_ITEM glob_arr[1024];

where

//.h file
extern MY_ITEM glob_arr[1024];

class MyClass
{
public:
    MyClass()
    {
        //Start using glob_arr
        glob_arr[0].v = 0;
        //...
    }
};

并且

struct MY_ITEM{
    int v;
    WCHAR chrs[64];
};
< p > glob_arr 是在堆栈还是进程堆中分配的?< /p >
2个回答

9
C++术语中有自动、动态和静态存储。全局变量将驻留在静态存储区域 - 如何处理这一点取决于具体的实现方式。

+1。例如 这个答案 展示了一个实现决策的例子。 - Angew is no longer proud of SO
好的,你能解释一下——你所说的实现是什么意思? - c00000fd
1
@c00000fd 在正式的C/C++术语中,“实现”意味着为特定系统实现编译器。 - Lundin
@Lundin:我正在使用VS 2008编译器。 - c00000fd
@c00000fd 的确。这里的答案非常通用。在 VS 中,数组肯定存储在静态内存中。至于 VS 是否将此内存称为“.bss”或其他内容,我不知道。 - Lundin
在典型的Unix实现中,该数组将存储在.bss段或.data段中,具体取决于它是否有显式初始化。我非常确定Windows的行为类似,尽管我不确定段的名称。 - James Kanze

2

该变量既不存储在栈中也不存储在堆中。

glob_arr 具有静态存储期,由于您没有显式初始化它,因此它存储在程序的读/写RAM段中,通常称为 .bss


好的。我需要知道的原因是因为我不想为我的数组使用有限的堆栈大小。但现在它已经分配在静态存储中,我应该从堆中分配它——即使这涉及到更多的核心,你认为呢? - c00000fd
@JamesKanze:静态存储数组不是分配在EXE文件映像内吗?(因此使得生成的可执行文件更大。) - c00000fd
2
@c00000fd 不包括 .bss 段。可执行文件中只有其大小。在加载时,操作系统将分配内存并将其初始化为 0。(而且谁会关心可执行文件的大小呢?) - James Kanze
@JamesKanze:说得好,我不知道它是这样分配的。至于可执行文件的大小,一个大的静态数组可能会使其大小超过边缘。(除非现代编译器做出“某些魔法”来防止这种情况发生。) - c00000fd
1
有趣。如果你相信dumpbin(我想不出任何理由不相信),VS 2013不使用类似于.bss的东西(无论名称如何):初始化和未初始化的数据都出现在.data中,并且看起来有一个未初始化数据的映像。我不认为这是个问题;但很奇怪,因为当我编译时,char x[1000000000];几乎瞬间编译和加载,但是char x[1000000000] = {1};需要非常明显的时间(秒)才能编译、链接和加载以便执行。 - James Kanze
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接