2013-06-04 33 views
2

我的任務有一個小問題。整個程序是關於樹數據結構的,但我沒有問題。C - 數組的字符串(二維數組)和內存分配讓我不想要的字符

我的問題是關於一些基本的東西:從用戶輸入讀取字符串,然後將它們存儲在一個數組中列表

char str[1000]; 

fgets(str, 1000, stdin); 

int x = 0; 
int y = 0; 
int z = 0; 

char **list; 
list = (char**)malloc((x+1)*sizeof(char)); 
list[x] = (char*)malloc((y+1)*sizeof(char)); 

while(str[z] != '\n') 
{ 
    list[x][y] = str[z]; 
    z++; 

    if(str[z] == ',') 
    { 

     x++; 
     y = 0; 

     list = (char**)realloc(list, (x+1) * sizeof(char*)); 
     list[x] = (char*)malloc((y + 1)*sizeof(char)); 

     z++; 
     if(str[z] == ' ') // Skips space after the comma 
     { 
      z++; 
     } 

    } 
    else if(str[z] == '\n') 
    { 
     break; 
    } 
    else 
    { 
     y++; 
     list[x] = (char*)realloc(list[x], (y+1)*sizeof(char)); 

    } 

} 

我將這個列表數組傳遞給另一個函數。 作爲一個例子,輸入可以像

Abcde, Fghijk, Lmnop, Qrstu 

,我試圖以這些詞分成數組列表

Abcde 
Fghijk 
Lmnop 
Qrstu 

當我嘗試輸出字符串時,有時會出現奇怪的字符,例如顛倒的問號和數字。

printf("%s ", list[some_number]); 

讓我

Fghijk¿ 

Fghijk\200 

我所有的計劃如預期,除了它我有麻煩解決這個小問題的作品。即使使用相同的確切輸入,錯誤可能會出現也可能不會出現。我猜測它與內存分配有關?

感謝您的幫助!

+2

當你使用malloc時,不能保證你已經放在內存中的內容是什麼,你應該將它初始化爲NULL,或者至少null結束你的字符串。 – ChrisCM

+0

我可以看到你將這些東西傳遞給其他函數嗎?另外,這些參數如何傳遞到程序中?文件,控制檯等? – nerdenator

回答

3

您需要在新字符串的末尾放置'\ 0'。

2

查看大部分C庫函數,例如printfstrlen處理字符串,假定爲\0作爲所有的結束字符。否則,他們繼續讀取內存越界,或者使內存違規,或者得到一些值0並停止,並將內存中的所有字節解釋爲它們的相同extended ascii,因此您會遇到這樣一種奇怪的行爲。

因此,爲\0字符分配一個額外的字節並將其分配給最後一個字節。

0

要麼將​​變量初始化爲null,要麼像番茄說的那樣,在新字符串的末尾放置一個空字符。

C缺乏許多奢侈品程序員現在認爲當談到內存管理。你在malloc的正確路徑,但該功能只分配內存......它不清除它。因此,您的變量將具有正確的空間量(對於減少內存泄漏和溢出錯誤至關重要),但會充滿垃圾。這個垃圾可能是任何東西,在你的情況下,這是一個顛倒的問號。適當的,你不覺得嗎?

我可能是錯誤的,因爲我不能沒有更多的信息運行的代碼自己,但你的

char **list; 
list = (char**)malloc((x+1)*sizeof(char)); 
list[x] = (char*)malloc((y+1)*sizeof(char)); 

語句後,你會想要做這樣的事情:

list = NULL; 

清理垃圾等。此外,您可能會使用strlen()函數(包含在string.h中)來計算出您需要分配多少塊內存。

清理變量使用的空間是一個很好的練習,可以和C一起學習。很高興看到你學習它。