2011-08-19 83 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