разный вывод с другой версией gcc, когда код динамического массива использует c - PullRequest
1 голос
/ 02 апреля 2019

Я пишу программу о динамическом массиве на языке c, код:

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

Когда массив увеличивается, он выводит разный вывод, как показано ниже:

с использованием dev-cppс gcc 4.9:

gcc4.9

с использованием кода с gcc8.2

gcc8.2

с использованием онлайн-компилятора c :

online compiler

И последнее - мое ожидание.

1 Ответ

5 голосов
/ 02 апреля 2019

Проблема в том, что у вас неопределенное поведение, поэтому может случиться что угодно.Это может проявляться по-разному на разных машинах или компиляторах.Учтите это:

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

Здесь вы создаете новый массив, а затем присваиваете его адрес вектору.Однако, когда эта функция завершается, эта память становится недействительной.Вместо этого замените его следующим:

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

И вы получите следующий вывод:

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

И не забудьте free, когда закончите.Чтобы это работало должным образом, я бы рекомендовал изменить int arr[10]; на int arr = malloc(10*sizeof(int));, чтобы массив никогда не находился в стеке, а затем поставить free(Arr->arr); перед Arr->arr = arr; и free(array.arr); в концепрограмма.

...