2014-01-11 49 views
0

該程序旨在接收'n'的學生和他們的名字和排序 (沒有去分揀部分)。 我不知道爲什麼我的程序崩潰時,我測試它。 這是代碼:第一次使用Malloc和程序崩潰

#include<stdio.h> 
#include <stdlib.h> 
#define MaxNameLen 100 
int main() { 

    int n; 
    scanf("%d", &n); 
    char *names; 
    char **pointerToNames = (char **) malloc(n * sizeof(char)); 
    if (pointerToNames == NULL) 
     return 0; 

    int i; 

    for (i = 0; i <= n; i++) { 
     names = (char *) malloc(MaxNameLen); 
     gets(names); 
     pointerToNames[i] = names; 
    } 

    for (i = 0; i < n; i++) { 
     free(pointerToNames[i]); 
     free(names); 
    } 
} 
+1

什麼是'gets'? – haccks

+0

@haccks http://www.cplusplus.com/reference/cstdio/gets/ – Inisheer

+0

@Inisheer;抱歉!現在在C成爲歷史。 – haccks

回答

5

您有三個問題。第一個是你不爲「陣」分配足夠的條目:

malloc(n * sizeof(char)) 

應該

malloc(n * sizeof(char*)) 

第二個問題是讀循環:

for (i = 0; i <= n; i++) { 

這裏循環條件會導致你循環一次到多次,導致你寫超出你分配的內容(如果你解決了第一個問題)。在下一個循環中,循環中的條件應該是i < n

第三個問題是,你反覆釋放的最後一個字符串中的循環

for (i = 0; i < n; i++) { 
    free(pointerToNames[i]); 
    free(names); 
} 

當您在以上循環分配namespointerToNames[i],當循環完成names將指向你讀的最後一個字符串,所以namespointerToNames[n - 1]將指向相同的字符串。其他


兩個問題包括:你是不是釋放實際pointerToNames存儲你第一次分配。而且你不應該使用gets(它早已被棄用,甚至在最新的標準中被刪除)。改用fgets(或gets_s)。

另外,don't cast the return of malloc

1

你的第一個malloc是爲N指向字符的指針分配內存,但是你正在分配N字符,這可能會少得多的內存。

改變這一行:

char **pointerToNames = (char **) malloc(n * sizeof(char)); 

要這樣:

char **pointerToNames = malloc(n * sizeof(*pointerToNames)); 

除了:

for (i = 0; i < n; i++) { 
     free(pointerToNames[i]); 
     free(names); 

這將釋放內存指定索引,但你也可以自由names,剛巧成爲您用來分配內存的臨時指針,然後分配給cu rrent價值name到每一個eement。所以,沒有必要免費names

也許你會發現簡單的第二部分(適用於您的陣列中的每個元素分配內存的代碼)改成這樣:

for (i = 0; i < n; i++) { 
     pointerToNames[i] = malloc(MaxNameLen); 
     if (pointerToNames[i]) 
      fgets(pointerToNames[i], MaxNameLen-1, stdin); 
    } 

所以不再使用names和替代gets(),使用fgets()。請注意,for循環從0變爲N-1,而不是NpointerToNames[N]不是有效的數組元素。

相關問題