Ошибка сегментации вокруг strcpy? - PullRequest
5 голосов
/ 23 июня 2011

Я знаю, что ты будешь меня стучать по костяшкам пальцев, но.

Почему возникает ошибка сегментации

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

, когда это не

char *cmd;
cmd = "plop";

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

ps: на самом деле, я знаю, что что-то подобное до strcpy было бы лучше

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

, ноМне просто интересно, почему эта ошибка сегментации.

Спасибо!

Ответы [ 4 ]

9 голосов
/ 23 июня 2011

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

char * cmd;

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

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

strcpy(cmd, argv[0]);

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

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

cmd = "plop";

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

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

Первый способ - разместить данные в стеке, например:

char cmd[100]; // for instance

. Это выделяет массив из 100 char s в стеке.Тем не менее, это не обязательно надежно, потому что вы должны знать заранее, сколько памяти вам нужно.Стек также меньше, чем куча.Что приводит нас к варианту № 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, как только закончите.

5 голосов
/ 23 июня 2011

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

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

3 голосов
/ 23 июня 2011

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

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

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

1 голос
/ 23 июня 2011

Мне просто интересно, почему эта ошибка сегментации.

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

...