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

c segmentation-fault strcpy

12743 просмотра

4 ответа

71 Репутация автора

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

Почему это делает ошибку сегментации

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

когда это не

char *cmd;
cmd = "plop";

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

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

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

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

Спасибо !

Автор: roro Источник Размещён: 22.06.2011 11:31

Ответы (4)


5 плюса

22736 Репутация автора

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

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

Автор: Will A Размещён: 22.06.2011 11:34

1 плюс

69032 Репутация автора

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

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

Автор: Pascal Cuoq Размещён: 22.06.2011 11:35

9 плюса

26933 Репутация автора

Решение

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

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 chars в куче. Не забудьте освободить память, freeкогда закончите.

Автор: Etienne de Martel Размещён: 22.06.2011 11:42

3 плюса

6395 Репутация автора

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

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

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

Автор: mattn Размещён: 23.06.2011 12:34
Вопросы из категории :
32x32