Выделите память и сохраните строку в c

Мне было интересно, почему следующий код не работает

int main(int argc, char **argv) { char *test = (char*) malloc(12*sizeof(char)); test = "testingonly"; free(test); } 

Подумав об этом, я предположил, что сначала я выделяю пространство для 12 символов в памяти, но назначение в следующей строке создает массив символов в стеке, а адрес памяти, который передается для проверки. Поэтому free () пытается освободить место в стеке, которое не разрешено. Это верно?

Итак, какой был бы правильный подход для сохранения строки в куче? Является ли следующий общий способ?

 int main(int argc, char **argv) { char *test = (char*) malloc(12*sizeof(char)); strcpy(test, "testingonly"); free(test); } 

 char *test = (char*) malloc(12*sizeof(char)); +-+-+-+-+-+-+-+-+-+-+-+-+ test--->|x|x|x|x|x|x|x|x|x|x|x|x| (uninitialized memory, heap) +-+-+-+-+-+-+-+-+-+-+-+-+ test = "testingonly"; +-+-+-+-+-+-+-+-+-+-+-+-+ test + |x|x|x|x|x|x|x|x|x|x|x|x| | +-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+ +->|t|e|s|t|i|n|g|o|n|l|y|0| +-+-+-+-+-+-+-+-+-+-+-+-+ free(test); // error, because test is no longer pointing to allocated space. 

Вместо изменения test указателя вам нужно скопировать строку "testingonly" в выделенное место, используя, например, strcpy или use strdup . Обратите внимание, что такие функции, как malloc и strdup возвращают NULL если недостаточно памяти, и, следовательно, должны быть проверены.

 char *test = (char*) malloc(12*sizeof(char)); strcpy(test, "testingonly"); +-+-+-+-+-+-+-+-+-+-+-+-+ test--->|t|e|s|t|i|n|g|o|n|l|y|0| +-+-+-+-+-+-+-+-+-+-+-+-+ 

или же

 char *test = strdup("testingonly"); +-+-+-+-+-+-+-+-+-+-+-+-+ test--->|t|e|s|t|i|n|g|o|n|l|y|0| +-+-+-+-+-+-+-+-+-+-+-+-+ 

Вы уже ответили на свой вопрос. По сути, strcpy является подходящим способом копирования строки.

Первая версия не создает строку в стеке, но вы правы, что вам не разрешено free ее после назначения. Строковые литералы обычно хранятся в разделах постоянной памяти / только для чтения. Назначение ничего не копирует, просто делает test точку в этой области памяти. Вы не можете освободить его. Вы также не можете изменить эту строку.

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

Ну, ты прав. Теперь рассмотрим первую часть кода.

 char *test = (char*) malloc(12*sizeof(char)); 

Над кодом нет проблем.

 test = "testingonly"; 

Здесь вы изменили test указателя, приводящий к утечке памяти. И когда вы пытаетесь освободить вас, вы не освобождаете фактический выделенный указатель, а один «testonly» буквальный, указывающий на. Literal указывает на постоянную память, которая не может быть переопределена в обычных сценариях.

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

К вашему второму пункту да strcpy – обычный способ. Другими способами являются «memcpy», если вы копируете необработанные байты.

ПРИМЕЧАНИЕ. Литералы не хранятся в стеке. Но вы не можете изменить местоположение, где хранятся литералы.

код

 #include  int main(int argc, char **argv) { char *test = (char*) malloc(12*sizeof(char)); strcpy(test, "testingonly"); printf("string is: %s\n",test); free(test); return 0; } 

буду работать

Это для выделения памяти:

 char *string; string = (char *) malloc(15); 

Это для сохранения данных:

 strcpy(str, "kavitajain"); printf("String = %s, Address = %u\n", str, str);