Что заставляет мой массив заполняться нежелательными числами - PullRequest
0 голосов
/ 27 февраля 2019

Я пытаюсь реализовать набор 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 35 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;
    }
}

Это для назначения, поэтому я слежу за сигнатурами функций.Я привык делать список объявлений со связанным списком, а не массивами.

Ответы [ 3 ]

0 голосов
/ 27 февраля 2019

Давайте посмотрим на определение realloc (): содержимое будет неизменным в диапазоне от начала региона до минимума старого и нового размеров.Если новый размер больше старого, добавленная память не будет инициализирована .Поэтому я считаю, что вы не должны использовать if (iter-> set-> array [iter-> cur] == NULL) в set_hasnext (set_iter_t * iter), поскольку вы не инициализировали массив перераспределения в NULL.Другими словами, значение в массиве может быть случайным.

0 голосов
/ 28 февраля 2019

Два изменения, которые исправляют мою проблему:

В 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)

Благодаря Трану и Энтони.

0 голосов
/ 27 февраля 2019

В функции 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
...