2011-08-19 113 views
2

我寫了一段代碼來處理動態數組。想法是使用數組結構指針,其中數組的最後一個成員是NULL。我寫的代碼略有差異(使用整數而不是結構)。C動態數組問題

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

void list_add(int **list, int* value) { 
    for(int i = 0; true; i++) { 
     if(list[i] == NULL) { 
     list = realloc(list, (i+2) * sizeof(int*)); 
     list[i] = value; 
     list[i+1] = NULL; 
     break; 
     } 
    } 
} 

void list_init(int **list) { 
    int* x; 
    for(int i = 0; i < 100; i++) { 
     x = malloc(sizeof(int)); 
     *x = i; 
     list_add(list, x); 
    } 
} 

int main() { 
    int** l = malloc(sizeof(int*)); 
    l[0] = NULL; 
    list_init(l); 
} 

調試時,我發現只有前3個整數被添加到列表中。我似乎無法弄清楚爲什麼會發生這種情況。有任何想法嗎?

+0

你想分配多維數組? (在這種情況下是2)? – phoxis

+0

是否有一些原因 - 除了想使用NULL終結符 - 使用一個存儲結構,每個int需要一個malloc?這是非常低效和麻煩的。 –

+0

單字母變量名稱不好,'l',尤其如此(看起來像一個)。 –

回答

4

的問題是,在list_add()調用realloc()可能釋放內存塊*list並分配另一個。 list_add更新其list指針,但它不會將更新的指針返回給調用者list_init(); list_init()list指針可能是指向最近釋放的內存塊的指針。

爲了解決這個問題,list_add()list_init()需要能夠「迴歸」更新list指針:

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

void list_add(int ***p_list, int *value) { 
    int **list = *p_list; 
    int i; 
    for(i = 0; true; i++) { 
     if(list[i] == NULL) { 
     list = realloc(list, (i+2) * sizeof(int*)); 
     list[i] = value; 
     list[i+1] = NULL; 
     break; 
     } 
    } 
    *p_list = list; 
} 

void list_init(int ***p_list) { 
    int **list = *p_list; 
    int *x; 
    int i; 
    for(i = 0; i < 100; i++) { 
     x = malloc(sizeof(int)); 
     *x = i; 
     list_add(&list, x); 
    } 
    *p_list = list; 
} 

int main() { 
    int **list = malloc(sizeof(int*)); 
    list[0] = NULL; 
    list_init(&list); 

    int **l = list; 
    for (; *l != NULL; ++l) { 
     printf("%d\n", **l); 
    } 
} 

http://codepad.org/iGcSaJOR

+0

謝謝,這個作品。我從來沒有想過自己。 :) – Kijan

1

編輯

在這種情況下,動態數組,你告訴不會讓任何事情更好的方式,代碼只會變得複雜。對於每增加一個整數,您都會使用realloc積極嘗試節省內存,但執行時需要更多時間。爲什麼不分配一個爲數組保留的內存塊,並且要反映動態字符將數組放入具有最後一個索引的結構中,並且在添加內容時將它添加到最後一個位置並增加計數器。當這個塊被填充時,你可以鏈接另一個塊指向另一個塊。

typedef struct _dyna_arr 
{ 
    my_type data_arr[MAX_LEN]; 
    int n; 
    struct _dyna_arr *next block; 
}; 

因此,您維護多個數組的鏈接列表。 MAX_LEN的大小可以固定,這對於有助於減少內部碎片的應用程序來說是適當的。

* 舊的答案被刪除*

+0

這不是我想要實現的。我不想要2d數組,我需要一個指針數組,每個指針只指向一個整數(或結構)。 – Kijan

+0

@Kijan:我明白了,刪除了舊的答案,我認爲鏈式實現將更容易實現和處理。 – phoxis