C ++ строковый литерал тип хранения данных - PullRequest
21 голосов
/ 24 февраля 2010
void f()
{
    char *c = "Hello World!"
}

Где хранится строка? Что это за свойство? Я просто знаю, что это константа, что еще? Могу ли я вернуть его изнутри тела функции?

Ответы [ 8 ]

22 голосов
/ 24 февраля 2010

он упакован с вашим двоичным файлом - под упаковкой я имею в виду аппаратный, так что да, вы можете вернуть его и использовать в другом месте - вы не сможете его изменить, и я настоятельно рекомендую вам объявить :

const char * x = "hello world";
8 голосов
/ 24 февраля 2010

Строка хранится в области данных программы. Это полностью компилятор, формат исполняемого файла и зависит от платформы. Например, двоичный файл ELF помещает его в другое место, чем исполняемый файл Windows, и если вы компилировали для встроенной платформы, эти данные могут храниться в ПЗУ, а не в ОЗУ.

Вот иллюстрация макета формата ELF:

ELF Layout

Ваши строковые данные, скорее всего, будут найдены в разделах .data или .text, в зависимости от компилятора.

Вы, конечно, можете вернуть его изнутри тела функции. Просто сверьтесь с вашей реализацией, чтобы убедиться, что это произвольный доступ, так как многие реализации не позволят вам перезаписать его.

6 голосов
/ 24 февраля 2010

§2.14.15 Строковые литералы, раздел 7

Узкий строковый литерал имеет тип «массив из n const char», где n - размер строки, как определено ниже, и имеет статическая продолжительность хранения .

5 голосов
/ 24 февраля 2010

Обычно хранится в разделе памяти, доступном только для чтения, и имеет статическое распределение памяти.

Выполнение таких операций, как c[0] = 'k' и т. Д., Вызывает неопределенное поведение.

Могу ли я вернуть его из тела функции?

Да!

3 голосов
/ 24 февраля 2010

Он имеет статическую длительность хранения, поэтому существует на протяжении всей жизни программы.Точно, где компилятор / компоновщик поместил инициализированные данные, изменяется.Возвращение указателя на него из функции - это нормально, но обязательно верните char const * - запись в строку вызывает неопределенное поведение.

1 голос
/ 24 февраля 2010

Это реализация определена. Большую часть времени это будет храниться в таблице строк со всеми другими строками в вашей программе. Как правило, вы можете рассматривать ее как глобальную статическую переменную const, за исключением того, что она недоступна за пределами вашей функции.

0 голосов
/ 02 сентября 2017

Строковые литералы хранятся в сегменте DATA и распределяются во время компиляции. Это помогает назначать одинаковые строковые литералы нескольким переменным без создания копий строки.

например, char * str = "привет";

Str - это указатель на символ char, имеющий адрес char h, а "hello" хранится в сегменте данных и не может быть изменен. Попытка изменить его приведет к ошибке сегментации.

При присвоении строкового литерала массива char создается копия строки в стеке.

т.е. char str [] = "привет";

«Привет» копируется в стек (с добавлением нулевого символа) и str указывает на символ «h» в стеке.

0 голосов
/ 24 февраля 2010

Прошло много времени с тех пор, как я играл с C ++, но я помню, у меня (самоучка) было множество проблем со строками (ну, ладно, массивы символов ...).

Если вы вообще собираетесь изменять их значение, обязательно используйте ключевые слова new и delete ... Что-то в этом духе ...

char *strText = new char[10];
/* Do something
...
...
...
*/
delete [] strText;

Martin

...