【问题标题】:C ArrayList crashingC ArrayList 崩溃
【发布时间】:2017-02-19 15:55:31
【问题描述】:

我的数组列表文件:

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

当我将 10 个对象放入其中时,arraylist 工作正常。 但是当我在其中放入更多对象(100)时它会崩溃(内存访问冲突)。 它打印前 2 个对象,然后崩溃。

我该如何解决这个问题?

【问题讨论】:

  • 你为什么不用realloc
  • 你的堆有多大?

标签: c memory-management data-structures


【解决方案1】:

问题很可能是你如何复制内存:

memcpy(newSpace, oldSpace, oldCapacity);

第三个参数是大小以字节为单位。您需要将其与sizeof(void *) 相乘以获得正确的大小。

【讨论】:

  • 如果我破坏了这个数组列表,我是否也需要释放每个元素?
  • @user2997204 我想说这不是 arraylist 或其析构函数的责任,而是它的用户。如果列表中的指针指向未在堆上动态分配的数据怎么办?
【解决方案2】:

当您已经知道您的 arrylist 的大小时,声明 arrylist 的更好选择是

ArrayList *arrayList[size]

但如果您不知道大小,那么首选方法是使用链表。即创建一个元素并将其附加到您的列表中。

在您当前状态下可能有用的另一件事是使用

void *realloc(void *ptr, size_t size)

而不是在 ensureCapacity 函数中使用 malloc。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-27
    • 2019-10-24
    相关资源
    最近更新 更多