0

So I am working with this struct:

typedef struct {
    int capacity; // number of allocated elements
    int size; // number of elements
    int * p_data; // pointer to c-array of elements
} vector_t;

This is how I create this struct:

vector_t* createVector(int capacity){
    vector_t* v = (vector_t*) malloc(sizeof(vector_t));
    if(v == NULL){
        printf("ERROR: vector bad alloc\n");
        abort();
    }
    v->size = 0;
    v->capacity = capacity;

    printf("create vector with capacity: %d\n", v->capacity);

    v->p_data = (int*)malloc(sizeof(int) * capacity);

    if(v->p_data == NULL){
        printf("ERROR: int* bad alloc\n");
        abort();
    }

    return v;
}

And I want to insert items to my vector and after the size would be greater than the actual capacity I want to create a new vector with the capacity doubled. After I created the new vector I wanted to free the memory of the old vector and let the pointer point to the new vector

I am using this method to insert Data into the vector:

void insert(vector_t* v, int val){
    if(v == NULL){
        printf("ERROR: vector == NULL");
        return;
    }

    printf("BCapacity: %d\n", v->capacity);
    printf("BSize: %d\n", v->size);

    if(v->size >= v->capacity){
        vector_t* cv = createVector(v->capacity * 2);
    
        for(int i = 0; i < v->capacity; i++){
            cv->p_data[i] = v->p_data[i];
        }
        
        cv->size = v->size;

        free(v->p_data);
        free(v);
        v = NULL;
        v = cv;

        printf("INCapacity: %d\n", v->capacity);
        printf("INSize: %d\n", v->size);
    }

    v->p_data[v->size] = val;
    v->size++;

    printf("Capacity: %d\n", v->capacity);
    printf("Size: %d\n", v->size);
}

As you can see I added some debugging helpers (printf) and this is the output from them:

create vector with capacity: 10
BCapacity: 10
BSize: 0
Capacity: 10
Size: 1
BCapacity: 10
BSize: 1
Capacity: 10
Size: 2
BCapacity: 10
BSize: 2
Capacity: 10
Size: 3
BCapacity: 10
BSize: 3
Capacity: 10
Size: 4
BCapacity: 10
BSize: 4
Capacity: 10
Size: 5
BCapacity: 10
BSize: 5
Capacity: 10
Size: 6
BCapacity: 10
BSize: 6
Capacity: 10
Size: 7
BCapacity: 10
BSize: 7
Capacity: 10
Size: 8
BCapacity: 10
BSize: 8
Capacity: 10
Size: 9
BCapacity: 10
BSize: 9
Capacity: 10
Size: 10
BCapacity: 10
BSize: 10
create vector with capacity: 20
INCapacity: 20
INSize: 10
Capacity: 20
Size: 11
BCapacity: 0
BSize: 0
create vector with capacity: 0
INCapacity: -1672845440
INSize: 22051
Capacity: -1672845440
Size: 22052

As you can see the error occures when the memory of the old struct gets freed and the Pointer should point to the new Array.

I am sure its a pretty basic failure but I simply don't know how to fix it, help would be really appreciated.

Dejavu
  • 27
  • 1
  • 10
  • `void insert(vector_t* v, int val)` accepts a copy of the original pointer. You either need to pass a pointer to pointer `vector_t **v` or return the pointer and assign it outside the function if you want to make changes in the function visible outside it. – Retired Ninja Jul 21 '21 at 16:28

1 Answers1

2

You should only replace your data buffer, not whole vector. Something like this (create new buffer, copy, update buffer and capacity)

void insert(vector_t* v, int val){
if(v == NULL){
    printf("ERROR: vector == NULL");
    return;
}

printf("BCapacity: %d\n", v->capacity);
printf("BSize: %d\n", v->size);

if(v->size >= v->capacity){
    data_t new_buf = malloc(capacity * 2)
    memcopy(vec->buf, new_buf, vec->size)
    free(vec->buf)
    vec->buf = new_buf
    
    vec->cap = v->cap * 2;

    printf("INCapacity: %d\n", v->capacity);
    printf("INSize: %d\n", v->size);
}

v->p_data[v->size] = val;
v->size++;

printf("Capacity: %d\n", v->capacity);
printf("Size: %d\n", v->size);

}

bca
  • 444
  • 3
  • 12
  • @user3121023 Yes, realloc would be much better. It handles the copying and freeing the old area as I remember. – bca Jul 21 '21 at 17:12