读取命令行参数时出现分段错误

时间:2010-03-31 22:22:33

标签: c segmentation-fault

#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 个答案:

答案 0 :(得分:9)

argv,您将结束index <= argc。那应该是index < argc。请记住,数组索引从比数组的长度少一个。

(从1开始是正确的,因为argv[0]是程序名称。)

答案 1 :(得分:4)

strcat无效。它试图将数据连接到C运行时lib调用返回的缓冲区。您需要使用自己的缓冲区。并且你需要在getcwd()返回的缓冲区上使用free()方式(传入NULL会导致它分配内存)。

答案 2 :(得分:3)

getcwd()path分配一个大小等于size的缓冲区。您没有初始化size变量。设置它足够大以容纳整个路径和名称,这应该工作。如果缓冲区不够大,strcat()将写入缓冲区的末尾,覆盖堆栈上的其他值(可能包括函数返回指针,这将导致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

这可能不是你想要的:)。 (省略了输出的不相关行。)

答案 3 :(得分:2)

虽然关于strcat的答案是有效的,但鉴于程序崩溃的问题是一个NULL指针,因为你使用的是<= argc而不是< argc

在C中,argv[argc]是一个NULL指针。

答案 4 :(得分:1)

strcat(path,argv[index])正在向缓冲区添加数据,该缓冲区不足以容纳其他数据。

您应传入size值,以确保缓冲区足够大。你也没有初始化size,所以你真的不知道将返回什么大小的缓冲区(所有这些都假设你使用的是getcwd()的GNU libc版本,它将分配一个缓冲区如果你传入NULL)。

答案 5 :(得分:1)

你正在阅读argv的结尾。不要那样做。停在argc-1'论点。