Случай 1: char *str = "foo";
назначьте адрес строки в текстовом сегменте, который доступен только для чтения, и вы не можете записать его, как это сделано во второй строке: str[0] = 'b';
.Если вы хотите изменить текст, используйте char str[] = "foo";
, который создаст массив символов в стеке и присвойте его указатель на стр.
case 2: strlen
возвращает длину строки без символа '\0'
в конце, поэтому strlen("foo") = 3
, тогда как strcpy
копирует строку, включающую символ '\0'
, поэтому он копирует больше байтов, чем вы выделили.
дело 3: Как и в случае 1, str = "foo";
присваивая адрес «foo» str
, это означает, что вы теряете адрес выделенной памяти, а str
теперь содержит указатель на сегмент текста, который вы не можете free
потому что он не в куче, а только для чтения.
case 4: Функция free
не присваивает NULL
указателю, полученному в качестве параметра (поскольку он не имеет своего адреса, он не может этого сделать).И вы пытаетесь вызвать free
в буфере, который уже был free
d.
case 5: str[19]
- это char
, а не указатель на символ, а "%s"
ожидает строку, что означает char *
.Этот символ считается недействительным как адрес на многих платформах.printf()
не проверяет полученные аргументы.
case 6: Использование s->str
после s
является free
d неправильно.Правильное использование будет сначала позвонить free(s->str);
, а затем free(s);
.Освободите внутреннюю выделенную память перед free
загрузкой ее контейнера.