2013-04-18 37 views
0

實施rm命令這裏是一塊其編譯正常但在運行時是給分割故障代碼。 有人可以告訴我如何解決這個問題。代碼實現RM系統調用C.分段故障在linux

#include<sys/stat.h> 
#include<unistd.h> 
#include<dirent.h> 
#include<error.h> 
#include <stdio.h> 
#include <string.h> 


int rmq(char*pth) 
{ 
    char path[1000]; //hold the file name to be removed 
    strcpy(path,pth); 
    char *b; // stores the complete path of the file to be removed 
    struct dirent *d; 
    DIR *dir; 

    char cwd[256]; //holds current working directory 
    getcwd(cwd, sizeof(cwd)); 
    dir = opendir(cwd); 
    char path1[1000]; //for recursively moving through dir and subdir 
    strcpy(path1,cwd); 

    char newp[1000]; 
    struct stat buf; 

    while((d = readdir(dir))) //if there are directories to be read 
    { 
    if(!strcmp(d->d_name,".") || !strcmp(d->d_name,"..")) // skip "." and ".." 
    continue; 

    //appends directory read to cwd 

    strcpy(newp,path1); 
    strcat(newp,"/"); 
    strcat(newp,d->d_name); 
    //printf("%s>>",d->d_name); 

    if(stat(newp,&buf)==-1) // puts file info in buf 
     perror("stat"); 
    if(S_ISDIR(buf.st_mode))// if directory, then add a "/" to current path 
    { 
    //if a directory then call function again(recursion) 
     strcat(path1,"/"); 
     strcat(path1,d->d_name); 
     rmq(path1); 
    } 
    else{ 
     //if directory current read is the one to be removed 
     if((strcmp(path, d->d_name)) == 0){ 
     // append it with cwd & put it in b 
     b = malloc(25 + strlen(d->d_name) + 1); 
     sprintf(b, "%s/%s", "/home/urwa/Documents/OPS", d->d_name); 
     remove(b); // remove that file 
     free(b); 
     } 
    } 
} 
return 0; 
} 


int main(){ 
    char cwd[256]; 
    getcwd(cwd, sizeof(cwd)); 

    char *argv[2]; 
    argv[1] = "dumbledore.txt"; 
    rmq(argv[1]); // file to be removed is passed as parameter 
    return 0; 
} 

我想malloc的,但它並沒有解決問題

+2

火了GDB並找出它的失敗行:http://www.cs.cmu.edu/~gilpin/tutorial/ – paulsm4

+1

,請注意編譯器警告。如果你有警告,你的代碼不會*編譯好。 –

+2

你試圖'sprintf'到'B',這是一個'char',你想到了什麼事情發生呢? – Blindy

回答

6

你應該與-Wall -Wextra標誌代碼編譯絕對從編譯器的幫助下更好的效益。在這裏,你的代碼,你會得到以下警告:

test.c: In function ‘rmq’: 
test.c:9:4: warning: implicit declaration of function ‘strcpy’ [-Wimplicit-function-declaration] 
test.c:9:4: warning: incompatible implicit declaration of built-in function ‘strcpy’ [enabled by default] 
test.c:25:3: warning: suggest parentheses around assignment used as truth value [-Wparentheses] 
test.c:26:3: warning: implicit declaration of function ‘strcmp’ [-Wimplicit-function-declaration] 
test.c:30:5: warning: implicit declaration of function ‘strcat’ [-Wimplicit-function-declaration] 
test.c:30:5: warning: incompatible implicit declaration of built-in function ‘strcat’ [enabled by default] 
test.c:34:5: warning: implicit declaration of function ‘perror’ [-Wimplicit-function-declaration] 
test.c:43:5: warning: implicit declaration of function ‘sprintf’ [-Wimplicit-function-declaration] 
test.c:43:5: warning: incompatible implicit declaration of built-in function ‘sprintf’ [enabled by default] 
test.c:43:5: warning: passing argument 1 of ‘sprintf’ makes pointer from integer without a cast [enabled by default] 
test.c:43:5: note: expected ‘char *’ but argument is of type ‘char’ 
test.c:44:5: warning: implicit declaration of function ‘remove’ [-Wimplicit-function-declaration] 
test.c: In function ‘main’: 
test.c:58:2: warning: control reaches end of non-void function [-Wreturn-type] 
test.c: In function ‘rmq’: 
test.c:43:12: warning: ‘b’ may be used uninitialized in this function [-Wuninitialized] 

因此,解決所有問題的最好辦法就是要做到以下幾點:

  • 首先,缺少包括:

    #include <stdio.h> 
    #include <string.h> 
    
  • 在while測試中(編譯器需要確保您知道您在做什麼)在作業周圍添加額外的括號:

  • 您需要的char b;轉變爲char *b;和分配/解除分配必要的內存來存儲字符串:

    if((strcmp(path, d->d_name)) == 0){ 
        b = malloc(25 + strlen(d->d_name) + 1); 
        sprintf(b, "%s/%s", "/home/urwa/Documents/OPS", d->d_name); 
        remove(b); 
        free(b); 
    } 
    
  • 然後,你需要添加return 0main功能,以以匹配您定義的簽名。

一旦你完成了所有這些,仍然有一個錯誤,因爲你錯過了幾個例子。嘗試使用gdb和/或valgrind修復它(想想編譯時設置-g選項)。

+0

很好的答案。這導致了學習。 –

+0

@perror所以我改進了你提到的代碼。但它仍然給分段錯誤。 – urwaCFC

+1

@ user128806:出現該段錯誤,因爲你是用一個無限循環(您呼叫'連連rmq')飽和堆棧。你必須學習,如果你想在C – perror