2017-02-19 7 views
0

Meine Arraylist-Datei:C Arraylist Absturz

#include <stdint.h> 
#include <malloc.h> 
#include <memory.h> 
#include <stdio.h> 

#include "ArrayList.h" 


typedef struct ArrayList { 
    uint32_t size; 
    void **data; 

    uint32_t capacity; 
} ArrayList; 


ArrayList *arrayList_construct(uint32_t initialCapacity) { 
    if (initialCapacity < 10) { 
     initialCapacity = 10; 
    } 
    ArrayList *arrayList = malloc(sizeof(ArrayList)); 
    arrayList->size = 0; 
    arrayList->capacity = initialCapacity; 
    arrayList->data = malloc(initialCapacity * sizeof(void *)); 
    return arrayList; 
} 

void arrayList_add(ArrayList *arrayList, void *item) { 
    ensureCapacity(arrayList); 
    *(arrayList->data + arrayList->size) = item; 
    arrayList->size++; 
} 

void arrayList_set(ArrayList *arrayList, uint32_t index, void *value) { 
    *(arrayList->data + index) = value; 
} 

void *arrayList_get(ArrayList *arrayList, uint32_t index) { 
    return *(arrayList->data + index); 
} 

void arrayList_remove(ArrayList *arrayList, uint32_t index) { 
    memcpy(arrayList->data + index, arrayList->data + index + 1, (arrayList->size - index - 1) * sizeof(void *)); 
    free(*(arrayList->data + arrayList->size-- - 1)); 
} 

uint32_t arrayList_getSize(ArrayList *arrayList) { 
    return arrayList->size; 
} 

void arrayList_destruct(ArrayList *arrayList) { 
    free(arrayList->data); 
    free(arrayList); 
} 

static void ensureCapacity(ArrayList *arrayList) { 
    if (arrayList->size >= arrayList->capacity) { 
     uint32_t oldCapacity = arrayList->capacity; 
     uint32_t newCapacity = oldCapacity + (oldCapacity >> 1) * 2; 
     arrayList->capacity = newCapacity; 

     void **newSpace = malloc(sizeof(void *) * newCapacity); 
     void **oldSpace = arrayList->data; 
     arrayList->data = memcpy(newSpace, oldSpace, oldCapacity); 
     free(oldSpace); 
    } 
} 

int main() { 
    ArrayList *arrayList = arrayList_construct((uint32_t) 10); 


    int *array = malloc(100 * sizeof(int)); 
    for (int i = 0; i < 100; ++i) { 
     *(array + i) = i; 
     arrayList_add(arrayList, array + i); 
    } 

    for (int i = 0; i < arrayList_getSize(arrayList); i++) { 
     printf("[%p]: %d\n", arrayList_get(arrayList, i), *(int *) arrayList_get(arrayList, i)); 
    } 

    return 0; 
} 

Die Arraylist funktioniert gut, wenn ich in ihm 10 Objekte setzen. Aber es stürzt ab (Speicherzugriffsverletzung), wenn ich mehr Objekte (100). Es druckt die ersten 2 Objekte und dann stürzt es ab.

Wie kann ich dieses Problem beheben?

+1

Warum verwenden Sie nicht ['realloc'] (http://en.cppreference.com/w/c/memory/realloc)? –

+0

Wie groß ist dein Haufen? –

Antwort

1

Das Problem ist höchstwahrscheinlich, wie Sie den Speicher kopieren:

memcpy(newSpace, oldSpace, oldCapacity); 

Das dritte Argument ist die Größe in Bytes. Sie müssen dies mit sizeof(void *) multiplizieren, um die richtige Größe zu erhalten.

+0

Wenn ich diese Arraylist zerstöre, muss ich auch jedes Element freigeben? – user2997204

+0

@ user2997204 Ich würde sagen, es ist nicht die Verantwortung der Arraylist oder seine Destruktor-Funktion, sondern für den Benutzer davon. Was ist, wenn die Zeiger in der Liste auf Daten zeigen, die nicht dynamisch auf dem Heap zugeordnet sind? –

0

Wenn Sie bereits die Größe Ihres arrylist wissen, um die bessere Option zu erklären ein arrylist

ArrayList *arrayList[size] 

sein würde, aber wenn Sie Größe nicht wissen, dann ist eine bevorzugte Art und Weise wäre verkettete Liste zu verwenden. d. h. erstellen Sie ein Element und hängen Sie es an Ihre Liste an.

andere Sache, die in Ihrem aktuellen Zustand nützlich sein kann, ist

void *realloc(void *ptr, size_t size) 

anstelle der Verwendung von malloc in ensureCapacity Funktion zu verwenden.