C sprintf вызывает ошибку сегментации - PullRequest
0 голосов
/ 04 марта 2010

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

Все работает нормально, кроме случаев, когда я передаю четное количество аргументов. Дочерний процесс успешно добавит первые два аргумента и вернет их, но затем, когда родительский элемент выполняет 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.

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

Ответы [ 3 ]

3 голосов
/ 04 марта 2010

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

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

2 голосов
/ 04 марта 2010

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

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

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

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

0 голосов
/ 04 марта 2010
        argc++;
        sprintf(argv[argc-1],"%d",tmp);

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

...