2017-02-19 51 views
0

我的ArrayList的文件:當我把10個對象在它çArrayList的崩潰

#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; 
} 

ArrayList中正常工作。 但是當我在其中放置更多的對象時,它崩潰(內存訪問衝突)(100)。 它打印前2個對象,然後崩潰。

我該如何解決這個問題?

+1

你爲什麼不使用['realloc'](http://en.cppreference.com/w/c/memory/realloc)? –

+0

你的堆有多大? –

回答

1

的問題是最有可能的,你是如何複製的記憶:

memcpy(newSpace, oldSpace, oldCapacity); 

第三個參數是在字節大小。您需要將其與sizeof(void *)相乘以獲得正確的大小。

+0

如果我毀掉這個數組列表,我是否需要釋放每個元素呢? – user2997204

+0

@ user2997204我會說這不是ArrayList或其析構函數的責任,而是它的用戶。如果列表中的指針指向未在堆上動態分配的數據,該怎麼辦? –

0

當你已經知道你的arrylist的尺寸,更好的選擇申報arrylist將

ArrayList *arrayList[size] 

,但如果你不知道大小,然後優選的方法是使用鏈表。即創建一個元素並將其附加到您的列表中。

,可以在你目前的狀態非常有用的另一件事是使用

void *realloc(void *ptr, size_t size) 

代替的ensureCapacity函數使用malloc。