Realloc в реализации списка отправляет сигнал SIGABRT при третьем вызове

typedef struct List {
    void **data;
    int dataSize;
    int count;
    int capacity;
} List;

List list_create(int dataSize) {
    List list;
    list.data = malloc(dataSize);
    list.dataSize = dataSize;
    list.count = 0;
    list.capacity = 1;
    return list;
}

void list_add(List *list, void *data) {
    if(list->count == list->capacity) {
        printf("INCREASING LIST...");
        void *temp = realloc(list->data, list->dataSize * list->capacity * 2);
        if(temp == NULL) {
            printf("FAILED\n");
            return;
        } else {
            printf("LIST INCREASED\n");
            list->data = temp;
        }
        list->dataSize = list->dataSize;
        list->count = list->count;
        list->capacity = list->capacity * 2;
    }

    list->data[list->count++] = data;
}

int main(int argc, char *argv[]) {
    List list = list_create(sizeof(int));
    int item1 = 5, item2 = 8, item3 = 3, item4 = 10, item5 = 15;
    list_add(&list, (void *)&item1);
    list_add(&list, (void *)&item2);
    list_add(&list, (void *)&item3);
    list_add(&list, (void *)&item4);
    list_add(&list, (void *)&item5);
    return 0;
}

Здесь у меня есть собственная реализация списка или массива динамического размера на C. Я тестирую его внутри своей основной функции, но только первые четыре вызова list_add успешны. При пятом вызове — это третий раз, когда список изменяет размер поддерживающего его массива — в следующей строке отправляется сигнал SIGABRT, и программа прерывается.

void *temp = realloc(list->data, list->dataSize * list->capacity * 2);

На данный момент я немного застрял, и я все еще новичок в управлении и распределении памяти в C.


person Cains    schedule 14.02.2015    source источник


Ответы (1)


Я думаю, проблема в том, что вы выделяете свой массив data на основе каждого элемента размером dataSize, но позже вы используете массив data, заполняя его указателями void *. Если вы планируете использовать массив для хранения указателей, размер массива следует указывать с помощью sizeof(void *). Это означает, что вам нужно изменить две строки, вызов malloc и вызов realloc, заменив dataSize на sizeof(void *).

Если вы не собирались хранить указатели в массиве, вам нужно будет изменить способ назначения массиву.

person JS1    schedule 14.02.2015
comment
Я не могу поверить, что меня так сильно перевернуло! Я действительно собирался хранить массив пустых указателей, и с моей стороны было глупо выделять размер, как если бы сами данные хранились в этом массиве. Теперь все работает отлично, большое спасибо за помощь! - person Cains; 14.02.2015