2012-02-17 73 views
1

我知道這個問題聽起來很愚蠢,但我已經盡我所能,似乎我不能有與此代碼解決的問題:當返回一個int值時Segfault;

struct bacon_statement* statms;// = (struct bacon_statement*)malloc(3000 * sizeof(struct bacon_statement)); 

int ind = 0; 
char** yay = strsplit(code, ";"); 
char* a = *yay; 

while (a != NULL) { 

    puts(a); 

    if (strncmp(a, "#", 1)) { 
     struct bacon_statement statm; 
     int valid = bacon_make_statement(a, statm); 
     if (valid != 0) { return valid; } 

     statms[sta] = statm; 
    } 

    sta++; 
    *(yay)++; 
    a = *yay; 
} 

puts("Running BACON INTERNAL MAKE"); 
int ret = bacon_internal_make(statms, internal); 
printf("%d\n", ret); 
return ret; 

它出現segfaults當return ING,因爲它的printf是執行正常,另一個printf調用/之後/函數被調用(在int main())根本不打印任何東西。

對不起,如果這聽起來太具體,但我不知道還有什麼地方可以得到幫助。

+0

爲什麼你的malloc註釋掉?沒有它,對'statms [']的分配就無法工作。而且,它在返回時發生段錯誤,這意味着你可能在棧上覆蓋了某些東西,例如返回嘗試返回垃圾。在退貨之前發生錯誤。 – Irfy 2012-02-17 00:57:38

+0

此外,向我們展示'bacon_ *'函數的實現將是必不可少的,因爲問題可能在那裏。使它更加容易和:這使得它很煩人(中,也許,politer條款 - 此外,使用像'了'和'變量問什麼時候尋求幫助,因爲閱讀國外代碼往往夠繁瑣yay'幾乎是一種侮辱很可能讓其他人通過使用更有意義的變量/函數/等名稱來幫助你)。 – Irfy 2012-02-17 01:02:54

+1

您也不會顯示'sta'的聲明或初始化。 – 2012-02-17 01:06:35

回答

3

顯然你以某種方式破壞了堆棧。 你行不初始化指針:

struct bacon_statement* statms;// = (struct bacon_statement*)malloc(3000 * sizeof(struct bacon_statement)); 

,但你寫它是這樣,這將有不確定的操作:

statms[sta] = statm; 

最簡單的方式來解決可能是恢復的malloc(提供的大小是正確的)

struct bacon_statement* statms = (struct bacon_statement*)malloc(3000 * sizeof(struct bacon_statement)); 
2

看起來像堆棧溢出,您不斷檢查邊界,將數據分配給緩衝區(statms)。遲早,返回地址(位於堆棧上)將被覆蓋,當返回時,返回的地址將被破壞。並有你的分段錯誤。

1

嘗試做這樣的事情:

int count = 0; 
char *ptr = strchr(code, ';'); 
while (ptr) { 
    count++; 
    ptr = strchr(ptr + 1, ';'); 
} 

預測語句的數量,然後:

struct bacon_statement* statms = (struct bacon_statement*) malloc(
    count * sizeof(struct bacon_statement)); 

分配足夠bacon_statement槽。替代品可能更難:鏈接列表或其他可變結構;或者使用realloc來增加數組的大小,記下你留下了多少個sots。

雖然錯誤仍然可以在其他功能!

0

有沒有可能是你想用的IND代替STA作爲數組索引變量,STA未初始化?

+0

編號* ind *只是我必須刪除的變量。 – Matoe 2012-02-17 01:23:10

1

代碼確實太多了。讓我來總結一下:

struct bacon_statement* statms;// = (struct bacon_statement*)malloc(3000 * sizeof(struct bacon_statement)); 

int ind = 0; 
char** yay = strsplit(code, ";"); 
char* a; 

while ((a = *yay)) { 

    puts(a); 

    if (strncmp(a, "#", 1)) { 
     struct bacon_statement statm; 
     int valid = bacon_make_statement(a, statm); 
     if (valid != 0) { return valid; } 

     statms[sta] = statm; 
    } 

    sta++; 
    *(yay)++; 
} 

puts("Running BACON INTERNAL MAKE"); 
int ret = bacon_internal_make(statms, internal); 
printf("%d\n", ret); 
return ret; 

但我們能比這更緊湊:

struct bacon_statement* statms;// = (struct bacon_statement*)malloc(3000 * sizeof(struct bacon_statement)); 

int ind = 0; 
char** yay;; 
char* a; 

for (yay = strsplit(code, ";"); (a = *yay); *(yay)++) { 

    puts(a); 

    if (strncmp(a, "#", 1)) { 
     struct bacon_statement statm; 
     int valid = bacon_make_statement(a, statm); 
     if (valid != 0) { return valid; } 

     statms[sta] = statm; 
    } 

    sta++; 
} 

puts("Running BACON INTERNAL MAKE"); 
int ret = bacon_internal_make(statms, internal); 
printf("%d\n", ret); 
return ret; 

現在讓我們去掉傻stringcompare:

struct bacon_statement* statms;// = (struct bacon_statement*)malloc(3000 * sizeof(struct bacon_statement)); 

int ind = 0; 
char** yay; 
char* a; 

for (yay = strsplit(code, ";"); (a = *yay); *(yay)++) { 

    puts(a); 

    if (*a != '#') { 
     struct bacon_statement statm; 
     int valid = bacon_make_statement(a, statm); 
     if (valid != 0) { return valid; } 

     statms[sta] = statm; 
    } 

    sta++; 
} 

puts("Running BACON INTERNAL MAKE"); 
int ret = bacon_internal_make(statms, internal); 
printf("%d\n", ret); 
return ret; 

還是沒有意義。 IMO希望通過一系列字符串指針(yay)循環並處理每個字符串。特別是*(yay)++看起來很尷尬。

也許用「#」他要跳過註釋。我希望是這樣的:

sta=0; 
for (yay = strsplit(code, ";"); (a = *yay); yay++) { 
    int err; 
    if (*a == '#') continue; 
    /* make bacon from a */ 
    err = bacon_make_statements(a, statms[sta]); 
    if (err) return err; 
    sta++; /* could overflow ... */ 
    } 

/* you need the number of assigned struct members ("sta") to this function */ 
return bacon_internal_make(statms,sta internal); 

關於第二個想法,我的猜測是,strsplit()函數返回一個指針自動(「堆棧」)變量。或者* yay變量增加超出識別範圍。或者statms []數組被索引超出範圍。