Ошибка сегментации при чтении аргументов командной строки - PullRequest
2 голосов
/ 01 апреля 2010
#include<stdio.h>
#include<zlib.h>
#include<unistd.h>
#include<string.h>


int main(int argc, char *argv[])
{
   char *path=NULL;
   size_t size;
   int index ;
   printf("\nArgument count is = %d", argc);
   printf ("\nThe 0th argument to the file is %s", argv[0]);
   path = getcwd(path, size);
   printf("\nThe current working directory is = %s", path);
   if (argc <= 1)
   {
      printf("\nUsage: ./output filename1 filename2 ...");
   }
   else if (argc > 1)
   {
      for (index = 1; index <= argc;index++)
      {
            printf("\n File name entered is = %s", argv[index]);
            strcat(path,argv[index]);
            printf("\n The complete path of the file name is = %s", path);
      }
   }
   return 0;
}

В приведенном выше коде вот вывод, который я получаю при выполнении кода:

$ ./output test.txt

Argument count is = 2
The 0th argument to the file is ./output
The current working directory is = /home/welcomeuser
 File name entered is = test.txt
 The complete path of the file name is = /home/welcomeusertest.txt
Segmentation fault (core dumped)

Может ли кто-нибудь, пожалуйста, понять, почему я получаю ошибку дампа памяти?

Ответы [ 6 ]

9 голосов
/ 01 апреля 2010

Вы выходите из конца argv, произнося index <= argc.Это должно быть index < argc.Помните, что индексы массива идут от ноль до на единицу меньше, чем длина массива .

(Вы можете начать с 1, потому что argv[0] это имя программы.)

4 голосов
/ 01 апреля 2010

strcat недействительно. Он пытается объединить данные в буфер, возвращаемый вызовом lib среды выполнения C. Вам нужно использовать свой собственный буфер. И вам нужно использовать free () в буфере, возвращаемом getcwd () так, как вы его используете (передача в NULL заставляет его выделять память).

3 голосов
/ 01 апреля 2010

getcwd() выделяет буфер для path размера, равного size. Вы не инициализировали переменную size. Установите его достаточно большим, чтобы вместить весь путь и имя, и это должно работать. Если буфер недостаточно велик, strcat() будет записывать после конца буфера, перезаписывая другие значения в стеке (возможно, включая указатель возврата функции, что приведет к ошибке segfault на return).

Кроме того, getcwd() использует malloc() для выделения буфера, который вы назначаете для path. Было бы неплохо free() этот буфер, когда вы закончите с ним. Хотя это не является строго необходимым в конце программы - поскольку система все равно будет восстанавливать память.

В вашем коде также есть некоторые логические ошибки. Во-первых, индексы массива argv находятся в диапазоне от 0 до argc -1. Ваше условие выхода из цикла for заставляет вас читать один элемент после конца массива argv .

Обратите внимание, что strcat() будет добавлять новый параметр на каждой итерации к результату предыдущей итерации . Это означает, что вызов /home$ ./output foo bar baz закончится:

The complete path of the file name is = /home/foo
The complete path of the file name is = /home/foobar
The complete path of the file name is = /home/foobarbaz

Что, вероятно, не то, что вы хотите :). (опущены нерелевантные строки вывода).

2 голосов
/ 01 апреля 2010

Несмотря на то, что ответы о strcat являются действительными, учитывая точку, в которой ваша программа дает сбой, проблема является пустым указателем, поскольку вы используете <= argc, а не < argc.

В C argv[argc] - это нулевой указатель.

1 голос
/ 01 апреля 2010

Вы читаете с конца argv. Не делай этого. Остановитесь на argc-1 '-ом аргументе.

1 голос
/ 01 апреля 2010

strcat(path,argv[index]) добавляет данные в буфер, которого недостаточно для хранения дополнительных данных.

Вы должны передать значение size, которое обеспечит достаточно большой буфер. Вы также не инициализируете size, поэтому вы действительно не знаете, какой размер буфера будет возвращен (все это предполагает, что вы используете GNU libc версию getcwd(), которая будет выделять буфер, если вы передадите NULL).

...