簡體   English   中英

讀取命令行參數時出現分段錯誤

[英]Segmentation fault when reading command line arguments

#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)

誰能讓我理解為什么我會收到核心轉儲錯誤?

您將通過index <= argc結束argv 那應該是index < argc 請記住,數組索引從小於數組的長度

(你從1開始是正確的,因為argv[0]是程序名。)

strcat無效。 它試圖將數據連接到C運行時lib調用返回的緩沖區。 您需要使用自己的緩沖區。 並且你需要在getcwd()以你使用它的方式使用的緩沖區上使用free()(傳入NULL會導致它分配內存)。

getcwd()為大小等於size path分配緩沖區。 您沒有初始化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

這可能不是你想要的:)。 (省略了輸出的不相關行)。

雖然關於strcat的答案是有效的,但鑒於程序崩潰的問題是一個NULL指針,因為你使用<= argc而不是< argc

在C中, argv[argc]是一個NULL指針。

strcat(path,argv[index])正在向緩沖區添加數據,該緩沖區不足以容納其他數據。

您應傳入一個size值,以確保緩沖區足夠大。 你也沒有初始化size ,所以你真的不知道將返回什么大小的緩沖區(所有這一切都假設你正在使用getcwd()的GNU libc版本,如果你傳入NULL,它將分配一個緩沖區) 。

你正在閱讀argv的結尾。 不要那樣做。 停在argc-1的論點上。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM