关于C++ String(类)声明全局对象在内存中的位置分析

目录

 

1.引言

2.验证方法

2.1STL容器验证C++代码及运行

2.2结果分析

2.3自定义类验证C++代码及运行

2.4结果分析

3.结论


1.引言

在C++中,对于int,float等基本类型变量而言,如果是声明为全局变量,则毫无疑问位于静态存储区(初始化在data段,未初始化在bss段),对于string这样的stl容器,由于动态扩展的需要,则都是在堆上进行空间分配。在一次面试过程中,被面试官问道string对象声明为全局变量,则该对象的内存空间位于哪里?

当时有点懵,感觉挺矛盾的,因此,面试结束后写代码进行验证;

2.验证方法

创建以下变量和对象,

  • 全局初始化对象
  • 全局未初始化对象
  • 全局初始化变量
  • 全局未初始化变量
  • 局部string对象

取对象的地址判断地址是在内存中的哪个区域;

2.1STL容器验证C++代码及运行

#include 

#include 

using namespace std;

string str="hello";

string str2;

int a=10;

int b;

int main()

{

    string str3="world";

    cout<<"a address:"<<&a<

在ubuntu系统下运行g++编译为二进制文件

g++ -o test.o test.cpp

可执行文件test.o是elf文件,使用readelf命令可以读取elf文件信息,获取程序内存空间的地址信息

readelf -S test.o>>m.txt

2.2结果分析

关于C++ String(类)声明全局对象在内存中的位置分析_第1张图片

(1).data段

从输出文件m.txt中可以看到静态区.data段的起始地址为0x602098,data段的大小为0x14个字节,上述变量和对象中,只有全局初始化变量a(地址0x6020a8)位于.data段,而str对象的地址为0x6021d8

(2).bss段

静态区.bss段的起始地址为0x6020c0,.bss段大小为0x130字节,则其地址范围0x6020c0~0x6021F0 ,上述变量和对象中,全局未初始化变量b(地址0x6021e8),全局初始化string对象str(0x6021d8)和全局未初始化对象str2(0x6021e0)都位于这个范围内;

(3)堆

局部string对象str3地址不在.data和.bss段内,在堆上。

2.3自定义类验证C++代码及运行

基于上述结果,无论stl是否初始化,其声明的全局对象都是位于.bss段内,进而考虑自定义的类如果声明全局对象其内存位置在哪里?

以下代码定义了一个类Ctest,并声明了一个全局对象和一个动态创造的对象;同样通过g++和readelf分析内存位置

#include 
using namespace std;
class Ctest{
private:
	int width;
	int height;
public:
	Ctest(int w,int h):width(w),height(h)
	{
		cout<<"construct"<

2.4结果分析

关于C++ String(类)声明全局对象在内存中的位置分析_第2张图片

(1).data段

全局初始化变量width和height位于.data段内

(2).bss段

.bss段起始地址0x6020a0,大小为0x120,所以.bss段的地址范围0x6020a0~0x6021c0,自定义类Ctest声明的全局对象square1的地址0x6021b4位于.bss段内

3.结论

从测试结果来看,对于类这样的数据类型,如果声明了全局对象,其内存位置位于.bss段,猜测是类这样数据类型需要在运行的时候调用构造函数才能创建对象,对于声明的全局对象,程序会在进入main函数前调用其构造函数创造对象。

(个人观点,不保证正确性,希望大佬看到后能给予指正!)

你可能感兴趣的:(C++,c++)