Ошибка сегментации вокруг strcpy?

Я знаю, что ты ударишь меня по костяшкам, но.

Почему возникает segmentation fault

char* cmd; strcpy(cmd, argv[0]); 

когда это не

 char *cmd; cmd = "plop"; 

Некоторое время я не практиковал, и не могу вспомнить, почему.

ps: На самом деле, я знаю, что что-то вроде этого, до strcpy, будет лучше

 char *cmd = (char*) malloc(strlen(argv[0])); 

но я просто задаюсь вопросом, почему эта segmentation fault.

Спасибо !

Когда вы выполните:

 char * cmd; 

Вы выделяете указатель на стек . Этот указатель не инициализируется никаким значимым значением.

Затем, когда вы это сделаете:

 strcpy(cmd, argv[0]); 

Вы копируете строку, содержащуюся в argv[0] к адресу, указанному в cmd , что … что-то бессмысленное. Поскольку вам повезло, это просто segfaults.

Когда вы это сделаете:

 cmd = "plop"; 

Вы назначаете cmd адрес статически выделенной строковой константе. Так как такие строки только для чтения, запись на них – неопределенное поведение.

Итак, как это решить? Выделите память для времени выполнения для записи. Есть два способа:

Первый заключается в распределении данных в стеке, например:

 char cmd[100]; // for instance 

Это выделяет массив из 100 char в стеке. Тем не менее, это не обязательно здорово, потому что вы должны заранее знать, сколько памяти вам понадобится. Стек также меньше, чем куча. Что приводит нас к варианту номер 2:

 char *cmd = malloc(whatever_you_need); // no need to cast, by the way, unless you're in C++ 

Это выделяет whatever_you_need char s в куче. Не забудьте освободить память free только вы закончите с ней.

Вы получаете сег. потому что cmd в вашем первом примере не указывает ни на что (или, скорее, указывает на то, что не определено), поэтому попытка считывать символы из или писать символы в указатель, вероятно, приведет к нарушению доступа).

Во втором примере вы устанавливаете cmd для указания законной строки символов.

Если вы хотите сделать копию argv [0] легко,

 char* cmd = strdup(argv[0]); 

Конечно, вам лучше проверить результат strdup, ноль или нет. 🙂

Я просто задаюсь вопросом, почему эта segmentation fault.

Потому что, если cmd является глобальной переменной, ее значение равно NULL , которое не доступно для записи, и если это локальная переменная, то ее значение является неопределенным, и вы не должны его использовать (но оно может сделать что угодно, если вы это сделаете, что хуже, чем NULL во многих случаях).