C ++中的全局对象

时间:2010-12-09 05:18:52

标签: c++

在以下C ++代码中,s分配在哪里?它是使用堆,数据,bss还是某种组合?我在Linux / x86平台上,以防万一。有没有办法让g ++编译器向我展示布局?

#include <string>
#include <iostream>

using namespace std;

string s;

int main()
{
    s = "test";
    cout << s;
}

2 个答案:

答案 0 :(得分:2)

字符串'object'将位于数据段中。

但它会在堆上有一些动态分配(例如,用于保存实际的字符串字符)。

编辑:正确评论时,“字符串”无法使用动态分配。例如,如果字符串很短,则可以保留在内部。这取决于实现。

您可以检查对象本身的地址及其包含的指针,以查看事物的位置。如果你知道你的特定可执行文件的内存映射,你可以告诉你生活在哪里。

答案 1 :(得分:2)

C ++标准没有定义编译器放置这些对象的位置,但在UNIX上,认为字符串数据是:

是合理的。
  • 在BSS上,默认构造函数在main()
  • 之前运行
  • 在BSS上,编译器确定所有成员都为0,即使默认构造函数运行,因此根本不运行构造函数
  • 在数据段中,默认构造函数在main()
  • 之前运行
  • 在数据段中,成员变量的初始值由编译器计算并直接写入二进制图像

鉴于实现并且未定义std :: string的成员,通常不清楚任何成员在默认初始化之后是否应该最终为非0,这就是为什么有这么多可能性。

在使用GCC的Linux上进行编译而没有进行优化,然后用“nm -C”检查可执行文件,我碰巧在BSS上有's'。

 ~/dev  nm -C bss | grep ' s$'
08048896 t global constructors keyed to s
08049c98 B s

man nm

...
       "B" The  symbol  is  in  the  uninitialized data section (known as
           BSS).

虽然静态字符串对象永远不在堆上,但是如果为任何(可选)内部缓冲区分配的字符串太大,它们包含的一个或多个指针最终可能会指向堆上的内存。同样,没有具体的规则可以说他们不会为其他目的分配堆内存,或者为文本内容预先分配堆,即使它仍然是空的(但这很愚蠢)。