2013-10-15 19 views
-1

我有一個系統操作類的介紹,它有兩個不同的部分,第一個是一個簡單的程序,用於逐字節地讀取可執行文件,並輸出輸入的字符串至少有4個字符。這是一個可以在UNIX中使用的字符串程序(命令)的簡單建模。C字節讀取器中的分段錯誤(核心轉儲)

我對我提供的三個單獨的示例可執行文件有分段錯誤(核心轉儲)錯誤。我明白,這基本上意味着我試圖訪問一些我無法訪問的內存地址(通過超出程序擁有的分配塊或通過其他方式)。不幸的是,我不明白爲什麼這個程序正在這樣做。

我認爲問題在於我的鏈表實現 - 我用它來存儲可讀的字符,然後檢查鏈接列表是否有4個條目,當不可讀的字符出現時。如果是這樣,我打印它。然後清除鏈接列表並重新開始。

我遍歷文件逐字節,我覺得這個程序的邏輯是健全的。但是,我對指針,地址和malloc的完整理解並不完善。由於缺乏這方面的知識,我預感到分段故障正在發生。

有人可以看看下面的代碼,並找出我做錯了什麼?最重要的是,你能解釋我濫用的概念嗎?爲什麼?我擔心該計劃的運作方式,是的,但也擔心我缺乏理解。代碼如下 - 謝謝。

#include <stdio.h> 
#include <stdlib.h> 

struct node{ 
    char ANSII; 
    struct node *next_node; 
}; 

void clear_list(struct node *first_node); 
void print(struct node *first_node); 
int counter(struct node *first_node); 
void append(char temp, struct node *first_node); 


int main(int argc, char **argv){ 
    FILE *f = NULL; 
    struct node header; 
    char temp; 

    if(argc != 2){ /* argv[0] = name of the program, argv[1] = file to open */ 
     printf("usage: %s filename:", argv[0]); 
    } 

    f = fopen(argv[1], "rb"); 

    if(f == 0){ /* check for successful read */ 
     printf("Could not open file.\n"); 
    } 

    while(!feof(f)){ 
     fread(&temp, sizeof(1), 1, f); 
     if(temp >= 32 && temp <= 128){ /* If it falls between the bounds of printable  characters. */ 
      append(temp, &header); //Builds the string 
     }else{ 
      if(counter(&header) > 3){ 
       print(&header); 
      } 
      clear_list(&header); 
     } 
    } 
    return 0; 
} 
void clear_list(struct node *first_node){ 
    struct node *conductor; 
    while(first_node != NULL){ 
     conductor = first_node; 
     while(conductor->next_node != NULL){ 
      conductor = conductor->next_node; 
     } 
     free(conductor); 
    } 
} 
void print(struct node *first_node){ 
    struct node *conductor = first_node; 
    while(conductor != 0){ 
     printf("%s", conductor->ANSII); 
     conductor = conductor->next_node; 
    } 
    printf("\n"); 
} 
int counter(struct node *first_node){ 
    struct node *conductor = first_node; 
    int counter = 0; 
    while(conductor != 0){ 
     conductor = conductor->next_node; 
     counter++; 
    } 
    return counter; 
} 
void append(char temp, struct node *first_node){ 
    struct node *conductor = first_node; 
    while(conductor->next_node != 0){ 
     conductor = conductor->next_node; 
    } 
    conductor->next_node = malloc(sizeof(conductor->next_node)); 
    if(conductor->next_node == 0){ 
     printf("Memory allocation failed!"); 
     return; 
    } 
    conductor = conductor->next_node; 
    conductor->ANSII = temp; 
} 

我試過到目前爲止實施的答案,現在不是分割故障我得到:

*** glibc detected *** ./mystrings: double free or corruption (fasttop): 0x0000000000601250 *** 
======= Backtrace: ========= 
/lib64/libc.so.6[0x3886a75916] 
./mystrings[0x400798] 
./mystrings[0x40072f] 
/lib64/libc.so.6(__libc_start_main+0xfd)[0x3886a1ecdd] 
./mystrings[0x4005b9] 
======= Memory map: ======== 
00400000-00401000 r-xp 00000000 00:1b 1921384528       /afs/pitt.edu/home/n/a/nap54/private/cs449/project2/mystrings 
00600000-00601000 rw-p 00000000 00:1b 1921384528        /afs/pitt.edu/home/n/a/nap54/private/cs449/project2/mystrings 
00601000-00622000 rw-p 00000000 00:00 0         [heap] 
3886600000-3886620000 r-xp 00000000 fd:00 180       /lib64/ld-2.12.so 
388681f000-3886820000 r--p 0001f000 fd:00 180       /lib64/ld-2.12.so 
3886820000-3886821000 rw-p 00020000 fd:00 180       /lib64/ld-2.12.so 
3886821000-3886822000 rw-p 00000000 00:00 0 
3886a00000-3886b89000 r-xp 00000000 fd:00 183       /lib64/libc-2.12.so 
3886b89000-3886d89000 ---p 00189000 fd:00 183       /lib64/libc-2.12.so 
3886d89000-3886d8d000 r--p 00189000 fd:00 183       /lib64/libc-2.12.so 
3886d8d000-3886d8e000 rw-p 0018d000 fd:00 183       /lib64/libc- 2.12.so 
3886d8e000-3886d93000 rw-p 00000000 00:00 0 
388d200000-388d216000 r-xp 00000000 fd:00 6639       /lib64/libgcc_s-4.4.6-20120305.so.1 
388d216000-388d415000 ---p 00016000 fd:00 6639       /lib64/libgcc_s- 4.4.6-20120305.so.1 
388d415000-388d416000 rw-p 00015000 fd:00 6639       /lib64/libgcc_s- 4.4.6-20120305.so.1 
7ffff7fd5000-7ffff7fd8000 rw-p 00000000 00:00 0 
7ffff7ffb000-7ffff7ffe000 rw-p 00000000 00:00 0 
7ffff7ffe000-7ffff7fff000 r-xp 00000000 00:00 0       [vdso] 
7ffffffea000-7ffffffff000 rw-p 00000000 00:00 0       [stack] 
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0     [vsyscall] 
Aborted (core dumped) 

現在我完全喪失。有人可以擺脫(更多?)見解嗎?感謝您的幫助...

+1

不要做'while(!feof(...))'。例如, 'while(fread(...)!= 0)'。 –

+0

如果我這樣做(fread(...)!= 0),它會不會消耗字符,並且我將無法捕獲該字節? – Fiki

+1

只要將當前的'fread'調用移到'while'條件內。 –

回答

1

當您聲明變量header時,您不初始化成員。這意味着這些值將是不確定的和隨機的。然後,當您撥打成員最有可能不是NULL導致您取消引用未定義的指針並具有未定義的行爲。

main中至少初始化header結構的next_node成員。