Malloc делает строковые константы? - PullRequest
0 голосов
/ 24 февраля 2019

Прежде всего, прости меня, если это наивный вопрос;Я только начинающий, пытающийся учиться.

Я знаю, что:

  char* a = "CD"; 

Сохраняет строку в только для чтения памяти ;поэтому любые изменения в строках невозможны.(константа)

Но я знал, что это было так и при использовании malloc;

char* a = malloc(3*sizeof(char)) ;

a = "CD" ; 
a[0] = 'S' ; // even regular a = "MR"; does not work

Я так растерян, я думал, что это хранится в куче 1014* ...

Почему я не могу изменить строку?

Ответы [ 4 ]

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

Мне известно, что:

char* a = "CD"; 

Сохраняет строку в постоянной памяти;поэтому любые изменения в строках невозможны.(постоянная)

Зависит от того, как вы это видите.Стандарт C не обязывает строковые литералы попадать в постоянную память.На самом деле, стандарт C даже не требует, чтобы система имела только постоянную память.Однако, если вы попытаетесь изменить строковый литерал, поведение не определено.

Цитата из стандарта C11:

Не определено, различаются ли эти массивы при условии, что их элементы имеют соответствующийценности. Если программа пытается изменить такой массив, поведение не определено.

https://port70.net/~nsz/c/c11/n1570.html#6.4.5p7

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

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

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

Вы путаете указатель и распределение:

  • char* - указатель на некоторый символ в некотором месте в нашей памяти (это может быть или не быть кучей)
  • постоянная память, такая строка ("CD")
  • динамическое выделение в куче.

Хотя указатель может указывать либо на константу, либо на кучу, вы можете выполнить ту же операцию (например,: в вашем примере присвойте 0 с помощью 'S').Это не означает, что он всегда будет работать во время выполнения: они могут быть некоторой защитой от этого.

В худшем примере:

char* a = "CD";
char* b = "ZZ";
strcpy(a, "EFGHAAAAAAAAAAAA"); // may fail with Segmentation fault
printf("a: %3s, b: %3s\n", a, b); // may not work

Использование gcc (Gentoo 7.3.0-r3 p1.4) 7.3.0 и запуск программы приводят к Ошибка сегментации прямо на strcpy.

Вы можете использовать strcpy только в выделенной памяти:

char* a = malloc(3*sizeof(char)) ;
strcpy(a, "EFGHAAAAAAAAAAAA"); // may fail with Segmentation fault
printf("a: '%s'\n", a); // print a: 'EFGHAAAAAAAAAAAA'

При этом вы вышли за пределы: память, указанная символом a, может хранить до 3 символов, причем последним является \0.

. В этом случае (всегда?) следует использовать strncpy вместо:

char* a = malloc(3*sizeof(char));
strncpy(a, "EFGHAAAAAAAAAAAA", 3 );
a[2] = 0;

Кроме того, вы, вероятно, никогда не должны использовать char* с постоянной строкой, но const char* (компилятор может уже предупредить вас об этом, если не использовать -Wall):

const char* a = "CD" ; 
a[0] = 'S' ; // should not compile
0 голосов
/ 24 февраля 2019

a = "CD"; делает то же самое, что и char* a = "CD";: он сохраняет адрес "CD" в a.Значение, возвращаемое при вызове malloc, перезаписывается, и выделенная память просачивается.

Правильный способ сделать это - копировать строку:

strcpy(a, "CD");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...