其中是存储在内存中的字符串常量

Where are string constants stored in memory?

本文关键字:字符串 常量 内存 存储      更新时间:2023-10-16

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

我之所以这么问,是因为在以下问题中:

为什么创建静态conststd::字符串会导致异常?

达蒙的答案在最后有以下内容:

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

这样,你的常数是真正的(不仅仅是形式上的(常数没有分配,没有异常的可能性,也没有双重内存用法在大多数情况下,它看起来和闻起来仍然像一根绳子。唯一显著的区别是string_view没有保证nul终止(但它指向的字符常量是的,所以这是无关紧要的(,而且它实际上是恒定的,不可修改。。。这正是你想要的。

难道连常数都不需要存储在内存中的某个地方吗?如果它们存储在内存中(因为内存是有限的(,难道不可能因为没有更多的内存而引发异常吗?

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

这意味着当你申报时

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

二进制文件中保留的静态数据是用于文字"foobar"(用作const char*(和存储std::string对象所需的空间的静态数据,该空间是存储其内容所需的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

现在,这个对象在编译时不是"预构造的"。它是在运行时构建的,标准并不能保证它何时准确发生(事实上,如果它发生在调用main之前,则无法捕获构造函数可能引发的任何异常(。

引用的string_viewconst char*的包装器,它不会浪费内存,因为它只存储指向内容的指针,而设计为可变的普通std::string则不是这样。

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

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

如果你对进程的内存布局感兴趣,我发现这篇博客文章非常有用。