是什么导致我的数组被多余的数字填充

时间:2019-02-27 19:06:09

标签: c arrays adt realloc

我正在尝试使用动态数组实现一组ADT。我有一组奇数和偶数。当数组已满时,我使用realloc获得更大的数组。 问题在于,这似乎也用多余的数字填充了数组。

struct set
{
    void **array;
    int numitems;
    int maxitems;
    cmpfunc_t cmpfunc;
};

void set_add(set_t *set, void *elem)
{
    if (!set_contains(set, elem))
    {
        if (set->numitems + 1 >= set->maxitems) // Make new bigger array if full
        {
            void **new_array = realloc(set->array, sizeof(void *) * set->maxitems * 2);
            if (new_array == NULL)
                printf("Error");
            set->maxitems *= 2;
            set->array = new_array;
        }
        set->array[set->numitems] = elem;
        set->numitems++;
    }
}

主要我用它来加数字。

for (i = 0; i <= n; i++) {
    if (i % 2 == 0)
        set_add(evens, numbers[i]);
    else
    {
        printset("Odd numbers":, odds);
        set_add(odds, numbers[i]);
    }
}

这是我得到的输出。

输出:

  • 奇数:1

  • 奇数:1 3

  • 奇数:1 3 5

...

  • 奇数:1 3 5 7 9 11 13 15 17 19 21 23 25 27 29

  • 奇数:1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31

  • 奇数:1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 17 18 19 20 21 22 23 24 25 26 27 28 29 30

  • 奇数:1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 18 19 20 21 22 23 24 25 26 27 28 29 30

...

添加31之后,数组maxsize(= 16)会加倍。有什么想法导致数组的其余部分被填充?这只是代码的一小部分,因此,如果这里似乎没有什么原因,我可以发布更多。

===添加信息:===

static void printset(char *prefix, set_t *set)
{
    set_iter_t *it;

    printf("%s", prefix);
    it = set_createiter(set);
    while (set_hasnext(it)) {
        int *p = set_next(it);
        printf(" %d", *p);
    }
    printf("\n");
    set_destroyiter(it);
}

set_iter_t *set_createiter(set_t *set)
{
    set_iter_t *iter = malloc(sizeof(set_iter_t));
    if (iter == NULL)
        return NULL;
    bobsort(set);
    iter->set = set;
    iter->cur = 0;

    return iter;
}

int set_hasnext(set_iter_t *iter)
{
    if (iter->set->array[iter->cur] == NULL)
        return 0;
    else
        return 1;
}

void *set_next(set_iter_t *iter)
{
    if (iter->set->array[iter->cur] == NULL)
        return NULL;
    else
    {
        void *elem = iter->set->array[iter->cur];
        iter->cur++;
        return elem;
    }
}

这是一个作业,所以我关注函数签名。我习惯用链接列表而不是数组来创建adt列表。

3 个答案:

答案 0 :(得分:0)

在功能set_add中,您应该更改if条件:

 if (set->numitems + 1 >= set->maxitems) // Make new bigger array if full

if (set->numitems  >= set->maxitems) // Make new bigger array if full

答案 1 :(得分:0)

让我们看一下realloc()的定义:从区域的开始到新旧大小的最小值之间的内容将保持不变。如果新大小大于旧大小,则添加的内存将不会初始化。 因此,我相信您不应在set_hasnext(set_iter_t * iter)中使用if(iter-> set-> array [iter-> cur] == NULL),因为您没有将重新分配数组初始化为NULL。换句话说,数组中的值可以是随机的。

答案 2 :(得分:0)

解决我的问题的两项两项更改:

在add_set()中,更改

if (set->numitems + 1 >= set->maxitems)

if (set->numitems  >= set->maxitems)

然后在set_hasnext()中更改

if (iter->set->array[iter->cur] == NULL)

if (iter->cur >= iter->set->numitems)

感谢Tran和Anthony。