Строковые литералы являются особым случаем в языке.Давайте посмотрим на ваш код поближе, чтобы лучше это понять:
Сначала вы выделяете буфер в памяти и присваиваете адрес этой памяти str
:
char* str = (char*)malloc(20*sizeof(char));
Затем выприсвойте строковый литерал str
.Это перезапишет то, что str
удерживалось ранее, поэтому вы потеряете свой динамически выделенный буфер, что случайно приведет к утечке памяти.Если вы хотите изменить выделенный буфер, вам нужно в какой-то момент разыменовать str
, как в str[0] = 'A'; str[1] = '\0';
.
str = "This is a string";
Итак, каково значение str
сейчас?Компилятор помещает все строковые литералы в статическую память, поэтому время жизни каждого строкового литерала в программе равно времени жизни всей программы.Это утверждение скомпилировано в простое присваивание, подобное str = (char*)0x1234
, где 0x1234
должен быть адресом, по которому компилятор поместил строковый литерал.
Это объясняет, почему это работает хорошо:
char* str = "This is a string";
Обратите также внимание, что статическая память не должна изменяться во время выполнения, поэтому вы должны использовать const char*
для этого назначения.
Так что в этом случае мы должны выделить памятьпробел?
Во многих случаях, например, когда вам нужно изменить буфер.Другими словами;когда вам нужно указать что-то, что не может быть статической строковой константой.