Alfredo Pipoli
Alfredo Pipoli

Reputation: 21

Re-add one element to a dynamic array list (after deleting it from memory)

i'm working about dynamic array lists in c. i've some problems when i try to re-add one element to one arraylist after the deallocation.

Struct:

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

Free array method:

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

Allocate and reallocate method:

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

Insert element to 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;
}

Main:

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

When i try to run the program, i haven't any error by the terminal and seems work fine. But when i try use the debugger i can see the segmentation fault and i don't know why (i use CLion IDE) sorry, i'm beginner in c language ^^'

Upvotes: 0

Views: 50

Answers (3)

ryyker
ryyker

Reputation: 23208

Without a minimal compilable verifiable example included in your post this will be limited to general suggestions:

One potential problem is that the prototype:

void array_list_check_and_realloc(array_list_t* array);

Needs to be changed to accommodate a pointer to the object that needs to be given memory:

void array_list_check_and_realloc(array_list_t **array) 

This will of coarse also change the way it is called, and the code inside that function.

Some comments on naming:
The struct used includes the member name array. The following prototypes also include an argument instance of the entire struct named array.:

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

Although legal, this is confusing.

Using the _t postfix to name your struct array_list_t is also not recommended for the reasons explained here.

Some comments on your struct construct:

When creating a struct that will be used for linked lists, it is common to include a structure tag, as you have done, but to also include a pointer instance of the struct as a member. This you have not done, but you should consider it.

For example, consider modifying your original struct from this:

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

to something more like this: (includes eliminating '_t' postfix from typedef name.)

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

Upvotes: 1

Jabberwocky
Jabberwocky

Reputation: 50776

Big problem here:

void* array_list_free(array_list_t* array) {
    free(array->array);
    free(array);   
    array->capacity = 0;  //<<< oups, array points nowhere here as it has been
    array->size = 0;      //    freed on the previous line....
    array->array = NULL;
}

remove the three lines starting with array-> from the function.

Upvotes: 1

John Bollinger
John Bollinger

Reputation: 180113

The problem (at least a problem) is is that array_list_free frees the array_list_t object itself, not just the internal dynamic array:

    free(array);

If that's not a problem in itself (which it is if that object was not dynamically allocated) then it is a problem to continue using that object afterward without allocating new space for it and initializing that space -- both in that function itself and after that function returns.

Speaking of initialization, an initialization function is notable by its absence from those you present. Perhaps you initialize your objects via ordinary initializers or default initialization, or perhaps you just omitted the function, but be aware that you must not rely on uninitialized objects.

Upvotes: 1

Related Questions