字符串常量存储在内存中的哪个位置?

时间:2016-11-04 04:42:06

标签: c++

在C ++程序中,存储的是常量数据,尤其是字符串常量?

我在问,因为在下面的问题中:

Why can creating a static const std::string cause an exception?

达蒙的回答,最后有以下几点:

  

与字符串相反,string_view不会分配非常量   内存,将常量数据复制到其中,然后假装它是常量。   相反,它将直接管理指向常量数据的指针,并且   就是这样。

     

那样,你的常数在那里真正(不仅仅是正式)不变   没有分配,没有异常的可能性,也没有双重内存   用法。在大多数情况下,它仍然看起来和闻起来像一个字符串。   唯一值得注意的差异是string_view没有   保证nul-termination(但它指向的字符常量)   是的,所以这是无关紧要的),以及它真的不变,   不可修改......这正是你想要的。

甚至连常量都需要存储在内存中的哪些地方?如果它们存储在内存中(因为内存是有限的),是不是可能因为没有更多内存而抛出异常?

2 个答案:

答案 0 :(得分:2)

问题是std::string是一个对象,而不仅仅是普通数据。

这意味着当您声明

static const std::string foobar = "foobar";

二进制文件中保留的静态数据是文字"foobar"(用作const char*)和存储std::string对象所需的空间,即< strong> NOT 存储其内容所需的空间。

想象一下std::string就像是,让我们说

class string {
private:
  size_t length;
  char* data;

public:
  string(const char* data) : length(strlen(data), data(new char[length+1]) {
    strcpy(this->data, data);
  }
  ~string() { delete data; }
};

这是一段微不足道的不安全代码,但它只是为了给你提供这个想法。当你拥有static std::string时,唯一需要的空间是sizeof(char*)+sizeof(size_t)字节,因为数据本身是在堆上动态分配的。

这就是为什么使用static const std::string浪费两倍的空间:对于文字本身,传递给字符串的构造函数,以及std::string

现在这个对象不是&#34;预构建的&#34;在编译时。它是在运行时和标准doesn't guarantee构造的,当它恰好发生时(事实上如果它在调用main之前发生,你将无法捕获构造函数可能抛出的任何异常)。

引用的string_viewconst char*的包装器,它不会浪费内存,因为它只存储指向内容的指针,而普通{{1}不是这种情况。设计为可变的。

答案 1 :(得分:1)

静态常量存储在&#39;数据中。可执行文件的一部分。它们存储的确切位置可能因系统而异,但在Linux的情况下,它们作为可执行文件的一部分加载并显示在文本段的正上方。在进程内存映射中。

在程序开始执行之前,操作系统将它们加载到进程内存映射中;因此,如果没有足够的内存,程序甚至无法加载,更不用说抛出异常了!

如果您对流程的内存布局感兴趣,我发现this blog post最有帮助。