2010-03-04 2 views
0

Я пытаюсь передать аргументы родительскому файлу, который должен создать дочерний процесс для каждой пары аргументов. Детские процессы будут складывать каждую пару и возвращать свою сумму в родительский процесс. Если имеется нечетное число аргументов, я добавляю 0 в конец массива argv, чтобы сделать его четным. Это продолжается до тех пор, пока все аргументы не будут добавлены, и их сумма будет напечатана в конце.C sprintf, вызывающий ошибку сегментации

Все работает нормально, за исключением случаев, когда я передаю ровное количество аргументов. Детский процесс успешно добавит первые два аргумента и вернет их, но тогда, когда родительский код имеет sprintf (строка 58), всегда есть segmentation fault.

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

Второй файл должен называться worker при компиляции для того, чтобы запустить в первом файле. Я использую gcc на Ubuntu 9.10

Вот несколько примеров того, как запустить программу:

gcc -o parent parent.c 
gcc -o worker worker.c 
./parent 1 2 3 4 

(В приведенном выше примере будет заканчиваться segmentation fault, как я объяснил выше). Ответ должен быть 10, потому что (1 + 2) + (3 + 4) = 10.

Это один ниже, хотя прекрасно работать с нечетным числом аргументов, передаваемых в:

./parent 1 2 3 

Ответ на этот должен быть 6.

Любая помощь была бы принята с благодарностью!

+2

Отправьте свой код здесь. –

+1

У вас есть ошибка. Ошибка не в 'sprintf'. –

+0

Это больше, чем ошибка; это непонимание того, как все работает. Кажется, что программа пытается сделать именно то, что он хочет, и это проблема :-) – Pointy

ответ

2

Стандарт C позволяет изменять строки указываемом по argv:

Параметры, argc и argv и строк, на которое указывает argv массив должен быть изменяемым программой, и сохранить их в последний раз - сохраненные значения между запуском программы и завершением программы.

Но это не гарантирует вам писать мимо доступного числа аргументов в argv, который является то, что вы делаете, когда вы храните сумму в конце argv.

Вы, кажется, используете argv[i] для char * переменных. Почему бы просто не объявить отдельные переменные с целью хранения суммы? Вам также не нужно хранить "0" в argv[argc-1], если количество чисел в сумме нечетное —, вы можете легко определить это в своем цикле и передать "0" последнему работнику.

+0

Спасибо, это имеет большой смысл! – Dave

3

Переопределение списка аргументов, в лучшем случае, является серьезным извращением, а в худшем - гарантированной ошибкой. Это то, что вы делаете в своем вызове sprintf - первый аргумент, который вы передаете, - это одна из строк, переданных в main(). Зачем ты это делаешь?

[править] Я вижу, что у вас есть комментарий к этому вопросу. Ну, я не знаю, что, как вы думаете, должно произойти, когда вы это сделаете; если вы объясните свое мышление, тогда кто-то сможет объяснить, с чем вы сбились с толку. Вы не можете добавить новый материал в массив argv. Это не имеет никакого смысла. Это то, что выделяется системой при запуске вашего процесса, и вы должны в основном относиться к нему как к чтению только (если вы действительно не знаете, что делаете).

+0

Спасибо за ваш ответ. Итак, я должен скопировать все новые суммы в отдельный целочисленный массив? Я думал, что могу просто сохранить цикл for, добавив все новые суммы в конце и увеличивая argc. – Dave

+0

Возможно, это доморощенный 'setproctitle'! :-P –

+0

@Dave, что вы ожидаете, произойдет, когда вы добавите строки в список аргументов? Другими словами, в чем цель? Что заставило вас подумать, что это хорошая идея? (Не высмеивая вас, я пытаюсь понять, что именно вы пытаетесь выполнить.) – Pointy

0
 argc++; 
     sprintf(argv[argc-1],"%d",tmp); 

Вы выходите из границ массива здесь. Кстати, что использовать для записи в argv?

+0

Здравствуйте, код, который вы положили, пишет, что я использую для добавления значений в массив argv. – Dave

+2

Красота C заключается в том, что это просто память. Массив argv не является массивом, как в PHP или javascript, где вы можете динамически добавлять элементы, и это понимает. Весь оператор [] делает доступ к куску памяти при заданном смещении. Поскольку размер массива фиксирован, вы пытаетесь получить доступ к части памяти вне ее контроля. Это может вызвать любое количество нечетных действий (от segfault до просто странных heisenbugs). Короче говоря, не делайте этого! :) – jdizzle

+0

Ха-ха, спасибо! – Dave