2016-11-04 5 views
0

В программе на C++, где хранятся постоянные данные, особенно строковые константы?Где хранятся строковые константы в памяти?

Я спрашиваю, потому что в следующий вопрос:

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

ответ, Дэймон, имеет следующую строку в конце:

string_view будет, в отличие от строки нет, выделять непостоянную память , копировать в нее постоянные данные, а затем притворяться постоянными. Вместо этого он будет управлять указателем непосредственно к постоянным данным, а - вот и все.

Таким образом, ваши константы действительно (не только формально) постоянны, там не являются выделениями, нет возможности исключений и нет двойной памяти . И по большей части он все еще выглядит и пахнет струной. Единственные заметные отличия в том, что string_view не гарантирует nul-term (но постоянная символа, указывающая на , делает это, так что это не имеет значения), и тот факт, что он действительно постоянный, не поддается изменению ... который именно то, что вы хотите.

Dont даже константы необходимо хранить в памяти, где? И если они хранятся в памяти (поскольку память конечна), разве нельзя ли исключить исключение, потому что больше нет памяти?

+2

Память для них загружается до запуска любого кода. Таким образом, исключение во время выполнения невозможно. Если вы можете запустить, то память уже есть. –

+1

связан с http://stackoverflow.com/questions/349025/is-a-string-literal-in-c-created-in-static-memory также https://isocpp.org/wiki/faq/ctors#static- INIT заказ –

ответ

2

Проблема в том, что объект 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.

Теперь этот объект не «предварительно построен» во время компиляции. Он сконструирован во время выполнения и стандартный doesn't guarantee, когда это происходит точно (действительно, если это произойдет до вызова main, вы не сможете поймать какое-либо исключение, которое может вызвать конструктор).

Приведенные string_view представляет собой оболочку вокруг const char*, который doens't память отходов, как он хранит только указатель на содержимое, которое не относится к нормальным std::string, который предназначен, чтобы быть изменяемым.

1

Статические константы хранятся в сегменте «данных» исполняемого файла. Точно там, где они хранятся, может отличаться от системы к системе, но, например, в Linux, они загружаются как часть исполняемого файла и отображаются непосредственно над «текстовым сегментом» на карте памяти процесса.

Они загружаются в карту памяти процесса операционной системой до запуска программы; поэтому, если для них недостаточно памяти, программа не может даже загружать, а тем более бросать исключение!

Если вас интересует компоновка памяти процессов, я нашел this blog post, чтобы быть наиболее полезным.

Смежные вопросы