2012-04-13 66 views
1

我複製了一些代碼,它只是將一個文件讀取到一個字符串並從舊程序中打印字符串。它工作正常,所以我決定修改一下。新方案是賦值給變量給出完全不相關的函數中的段錯誤

#include <stdio.h> 
#include <string.h> 

int main() { 
    FILE *itemlist = fopen("itemlist", "r"); 
    char *currentstring, charbuffer[2]; 
    // char itemstart = 0; 
    while (fgets(charbuffer, 2, itemlist)) { 
     strcat(currentstring, charbuffer); 
    } 
    printf("%s", currentstring); 
    return 0; 
} 

而且它按預期工作。但是,當我取消註釋itemstart行時,它會出現分段錯誤。我甚至沒有使用它,就我而言,初始化char爲0並不違法。我認爲這是一個類型的問題,然後我把它改爲short,然後改爲int,但它仍然給出了段錯誤。

但後來我刪除了= 0部分,它再次工作。然後我決定放回去,用gdb調試二進制文件,並且段錯誤位於strcat

這怎麼可能?

+0

什麼是'currenttring'指向? – geekosaur 2012-04-13 20:12:49

+0

目前沒有什麼,它只是一個空字符串。當我將'currenttring'指向NULL時,它會發生段錯誤。 – user1002327 2012-04-13 20:19:49

+2

這是修辭。你是對的,它指向* nothing *。隨機存儲器。當你修改隨機存儲器時,你會怎麼想?你認爲這是什麼意思,你可以隨意寫信給它? – geekosaur 2012-04-13 20:21:38

回答

4

currentstring是一個懸掛指針,所以strcat(currentstring, charbuffer);導致未定義的行爲。

大概取消註釋char itemstart = 0將一些內存初始化爲0,並且訪問衝突已可見,但這只是一種猜測。未定義的行爲意味着可能發生任何事情。

你應該爲currentstring分配內存:

currentstring = malloc(10); //or whatever length you need 
+0

你糾正了他的代碼,但你沒有回答他的問題:) – 2012-04-13 20:19:14

+0

這將是一個程序,它讀取一個格式爲'id = [name,properties,...]'的項目列表,因此每行的長度可能是10或150. – user1002327 2012-04-13 20:20:54

+0

@EldritchConundrum我做到了。未定義的行爲。再次閱讀答案。 – 2012-04-13 20:21:02

1

您需要爲電流串分配一些空間。

1

段錯誤時,在取消不相關的線由C語言的unsafeness成爲可能。不正確程序的最終行爲是由編譯器做出的微妙選擇決定的。

當面對這樣的瘋狂時,你應該嘗試先糾正你的代碼。這當然並不總是那麼容易。在8行程序中,你應該沒問題。

1

您必須爲currentstring變量分配空間並控制它的大小以避免段錯誤/堆損壞。

#define MAX_BUFFER_SIZE 32 
//... 
FILE *itemlist = fopen("itemlist", "r"); 
char *currentstring = malloc(MAX_BUFFER_SIZE+1); 
char *tmpbuf; 
char charbuffer[2]; 
// char itemstart = 0; 
int bytesloaded = 0; 
while (fgets(charbuffer, 2, itemlist)) { 

    if(bytesloaded + 2 > buf_size) { 
     /* call realloc() */ 
     buf_size += MAX_BUFFER_SIZE; 
     tmpbuf = realloc(currentstring, buf_size); 
     if(tmpbuf == NULL) { /* Get off loop. Using break or return. */ 
      break; 
     } 
     currentstrig = tmpbuf; 
    } 
    memcpy(currentstring + bytesloaded, charbuffer, 2); 
    bytesloaded += 2; 
} 
//... 
free(currentstring); 

我還沒有測試,但我相信它的工作原理。