Я попробовал ваш код, и также вижу segfault на втором strcat()
. Я обнаружил, что command[250]
выделяется сразу после whitespaceseparator[2]
в стеке моей системы:
(gdb) p &whitespaceseparator
$1 = (char (*)[2]) 0xbf90acd4
(gdb) p &command
$2 = (char (*)[250]) 0xbf90acd6
например. (здесь command
начинается "foo..."
), все выглядит так:
whitespaceseparator
|
| command
| |
v v
+---+---+---+---+---+---+---+---+
|' '| 0 |'f'|'o'|'o'|'.'|'.'|'.'| ...
+---+---+---+---+---+---+---+---+
Я не могу гарантировать, что то же самое происходит в вашей системе (расположение локальных стеков в стеке может отличаться даже для разных версий одного и того же компилятора), но это кажется вероятным По моему, именно так и происходит:
Как уже говорили другие, strcat()
добавляет вторую строку к первой (и результат будет равен первому аргументу). Итак, первое strcat()
переполняется whitespaceseparator[]
(и возвращает whitespaceseparator
как whitespace_and_pid
):
+---+---+---+---+---+---+---+---+
|' '|'1'|'2'|'3'|'4'| 0 |'.'|'.'| ...
+---+---+---+---+---+---+---+---+
Второй strcat()
пытается добавить whitespace_and_pid
(== whitespaceseparator
) к строке в command
. Первый символ копии перезапишет завершающий 0 строки в command
:
| ===copy===> |
v v
+---+---+---+---+---+---+---+---+
|' '|'1'|'2'|'3'|'4'|' '|'.'|'.'| ...
+---+---+---+---+---+---+---+---+
Копия продолжается ...
| ===copy===> |
v v
+---+---+---+---+---+---+---+---+
|' '|'1'|'2'|'3'|'4'|' '|'1'|'.'| ...
+---+---+---+---+---+---+---+---+
| ===copy===> |
v v
+---+---+---+---+---+---+---+---+
|' '|'1'|'2'|'3'|'4'|' '|'1'|'2'| ...
+---+---+---+---+---+---+---+---+
и будет продолжать копирование " 1234 1234 1234"
... до тех пор, пока оно не упадет в конец адресного пространства процесса, после чего вы получите ошибку сегмента.