将一个元素重新添加到动态数组列表中(从内存中删除后)

时间:2019-04-24 11:35:17

标签: c list dynamic malloc dynamic-memory-allocation

我正在研究c中的动态数组列表。 当我尝试在释放之后将一个元素重新添加到一个arraylist时遇到一些问题。

结构:

typedef struct array_list{
    void** array;
    size_t size;
    size_t capacity;
}array_list_t;

自由数组方法:

void* array_list_free(array_list_t* array) {
    free(array->array);
    free(array);
    array->capacity = 0;
    array->size = 0;
    array->array = NULL;
}

分配和重新分配方法:

void array_list_check_and_realloc(array_list_t* array) {
    if(!(array->capacity > array->size)) {
        if(array->capacity == 0){
            //the problem is probably here
            array->capacity++;
            array->array = realloc(array->array, sizeof(void*) * array->capacity);
        }else{
            array->capacity *= 2;
            array->array = realloc(array->array, sizeof(void*) * array->capacity);
        }
    }
}

将元素插入arraylist:

void* array_list_insert(array_list_t* array, void* element) {
    array_list_check_and_realloc(array);
    size_t i;
    for( i = array_list_size(array); i > 0; --i ) {
        array->array[i] = array->array[i-1];
    }
    array->array[i] = element;
    array->size += 1;
}

主要:

    array_list_insert(array,8);
    array_list_free(array);
    array_list_insert(array,8); // <--- Segmentation Fault

当我尝试运行该程序时,终端没有任何错误,并且看起来工作正常。但是当我尝试使用调试器时,我可以看到分段错误,而且我也不知道为什么(我使用CLion IDE) 抱歉,我是C语言的初学者^^'

3 个答案:

答案 0 :(得分:1)

问题(至少是 a 问题)是array_list_free释放了array_list_t对象本身,而不仅仅是内部动态数组:

    free(array);

如果这本身不是问题(即该对象不是动态分配的),那么在以后继续使用该对象而不为其分配新空间并初始化该空间是一个问题-两者都在该函数本身中然后该函数返回。

说到初始化,初始化功能因您不在场而引人注目。也许您是通过普通的初始化程序或默认的初始化程序来初始化对象的,或者只是省略了该函数,但要注意您一定不要依赖未初始化的对象。

答案 1 :(得分:1)

这里有大问题:

ProductStore

从函数中删除以result = result.Where(p => p.ProductId == DbContext.ProductStores.Select(m => m.Product) .OrderByDescending(m => m.Status).ToInt()); 开头的三行。

答案 2 :(得分:1)

您的帖子中未包含 minimal compilable verifiable example ,这仅限于一般建议:

一个潜在的问题是原型:

void array_list_check_and_realloc(array_list_t* array);

需要更改以容纳指向需要分配给内存的对象的指针:

void array_list_check_and_realloc(array_list_t **array) 

这种粗略的表示也会改变其调用方式以及该函数中的代码。

关于命名的一些评论:
使用的结构包括成员名称array。 以下原型还包含名为array的整个结构的参数实例。

void* array_list_free(array_list_t* array);
void array_list_check_and_realloc(array_list_t* array); 

尽管合法,但这令人困惑。

对于 reasons explained here ,也不建议使用_t后缀来命名结构array_list_t

关于您的struct构造的一些评论:

在创建将用于链表的结构时,通常会像您一样包含结构标签,但也将结构的指针实例作为成员包含在内。您尚未做到这一点,但您应该考虑一下。

例如,考虑从此修改您的原始结构:

typedef struct array_list{
    void** array;
    size_t size;
    size_t capacity;
}array_list_t;

更像这样:(包括从typedef名称中删除'_t'后缀。)

typedef struct array_list{
    size_t size;
    size_t capacity;
    struct array_list *array //this becomes new nodes of your list. 
}ListNode;