Ошибка сегментации при использовании strcpy ()? - PullRequest
0 голосов
/ 09 июня 2011

У меня есть глобальная структура:

struct thread_data{
   char *incall[10];
   int syscall arg_no;
   int client_socket;
};

и в main ()

char buffer[256];
char *incall[10];
struct thread_data arg_to_thread;

strcpy(incall[0],buffer);   /*works fine*/
strcpy(arg_to_thread.incall[0],buffer); /*causes segmentation fault*/

Почему это происходит, и, пожалуйста, предложите выход.

спасибо

Ответы [ 3 ]

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

Сегфоут означает, что что-то не так.Но no segfault не означает, что что-то не является неправильным.Если две ситуации в основном одинаковы, а одна - с ошибками, а другая - нет, это обычно означает, что они оба неверны, но только одна из них вызывает ошибку segfault.

Глядя на строку char* incall[10], это означает, что у вас есть массив из 10 указателей на символ.По умолчанию эти указатели будут указывать на случайные места.Поэтому при входе в incall [0] строка будет скопирована в произвольное место.Скорее всего, это будет Segfault!Сначала вам нужно инициализировать incall [0] (используя malloc).

Итак, более важный вопрос: почему не segfault первой строки?Я предполагаю, что причина в том, что просто так происходит , что все, что было в памяти раньше, было действительным указателем.Таким образом, strcpy не переходит в segfault, он просто перезаписывает что-то еще, что впоследствии вызывает совершенно неожиданное поведение.Поэтому вы должны исправить обе строки кода.

Другая проблема (после того, как вы исправили это) заключается в том, что strcpy сам по себе очень опасен - поскольку он копирует строки, пока не найдет 0Байт, а затем останавливается, вы никогда не можете быть точно уверены, сколько именно он будет копировать (если только вы не используете strlen для выделения целевой памяти).Так что вместо этого вы должны использовать strncpy, чтобы ограничить количество копируемых байтов размером буфера.

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

Вы не инициализировали указатель incall[0], поэтому, господи, знает только, куда записывает первый strcpy(). Вам не повезло, что ваша программа не падает сразу.

Вы не инициализировали указатель arg_to_thread.incall[0], поэтому, господи, знает только, куда записывает второй strcpy(). Вам повезло, что ваша программа вылетает сейчас, а не позже.

Ни в том, ни в другом случае это не ошибка компилятора; Вы всегда должны убедиться, что инициализируете свои указатели.

0 голосов
/ 09 июня 2011
  1. Убедитесь, что у вас достаточно памяти для ваших строковых буферов.
  2. Держитесь подальше от strcpy.Вместо этого используйте strncpy.strcpy - известный источник уязвимостей переполнения буфера - кошмар безопасности и обслуживания, для которого действительно нет оправдания.
...