1

I am code a program about dynamic array in c language, the code is :

#include <stdio.h>

struct Vector {
    int size;
    int capacity;
    int *arr;
};

void add(struct Vector *Arr, int data) {

    if (Arr->size == Arr->capacity) {
        Arr->capacity *= 2;
        int arr[Arr->capacity];

        //array copy
        for (int i = 0; i < Arr->size; i++) {
            arr[i] = Arr->arr[i];
        }

        Arr->arr = arr;
    }

    int size = Arr->size;
    Arr->arr[size] = data;
    Arr->size++;

}

void display(struct Vector *Arr) {
    for (int i = 0; i < Arr->size; i++) {
        printf("%d ", Arr->arr[i]);
    }
    printf("\n");
}

int main() {
    int arr[10];
    struct Vector
            array = {0, 10, arr};

    //fill the array
    for (int i = 0; i < 10; i++) {
        add(&array, i);
    }
    display(&array);
    //more element than the init size
    add(&array, 10);
    display(&array);    //where the error happened

    return 0;
}

When the array growth, it has defferent output like below:

using dev-cpp with gcc 4.9:

gcc4.9

using vs code with gcc8.2

gcc8.2

using the online c compiler:

online compiler

And the last one is my expectation.

3

1 Answer 1

5

The problem is that you have undefined behavior, so anything might happen. It can manifest in different ways on different machines or compilers. Consider this:

if (Arr->size == Arr->capacity) {
        Arr->capacity *= 2;
        int arr[Arr->capacity];
        ...
        Arr->arr = arr; // Arr->arr points to a local variable!

Here you're making a new array and then you are assigning its address to the vector. However, when that function finishes, that memory becomes invalid. Instead, replace it with this:

int *arr = malloc(sizeof(int) * Arr->capacity);

And you get the following output:

0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9 10

And don't forget to free it when you're done. To get that to work properly, I would recommend changing the int arr[10]; to int arr = malloc(10*sizeof(int)); so the array never is on the stack, then put a free(Arr->arr); before the Arr->arr = arr; as well as a free(array.arr); at the end of the program.

Sign up to request clarification or add additional context in comments.

4 Comments

he has an additional problem. The initial array storage is initialised with a literal. You can't free the address of that.
@RichardHodges that's right, which is why I suggested replacing int arr[10]; with int arr = malloc(10*sizeof(int)); so all of it can be freed.
Ah yes, didn't see that part. My apologies.
Got it! It is easily understood, nice answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.