2017-02-19 80 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。