Разница между динамическими массивами (GCC) и указателями - PullRequest
2 голосов
/ 28 мая 2019

Учитывая следующие фрагменты кода:

void foo() {
    int arraySize = getMyComputedValue();
    int dynamicArray[arraySize];

    fillDynamicArray(&dynamicArray[0]);

    for (int i = 0; i < arraySize; i++) {
        // Do something with data
    }
}

void bar() {
    int arraySize = getMyComputedValue();
    int* dynamicArray = new int[arraySize];

    fillDynamicArray(dynamicArray);

    for (int i = 0; i < arraySize; i++) {
        // Do something with data
    }

    delete[] dynamicArray;
    dynamicArray = NULL;
}

Оба создают динамическую область в памяти с переменной длиной, содержащей целые числа.Я обнаружил, что первый пример foo () (по крайней мере, в моей среде сборки) компилируется только с GCC.

Каковы точные различия между ними?Является ли первый пример просто расширением GNU, которое для нижнего примера является сокращением , позволяя компилятору определить, когда наступает правильное время для перераспределения?Или первый пример работает именно так, как говорит код, и выделяет память в стеке?

1 Ответ

4 голосов
/ 28 мая 2019
  1. foo() выделяет память в стеке, bar() выделяет ее в куче.Это имеет два эффекта: время жизни (память стека автоматически восстанавливается при выходе из функции) и максимальный размер массива (пространство стека довольно ограничено диапазоном не более нескольких МБ, пространство кучи ограничено только доступной оперативной памятью).

  2. foo() является действительным C99, но не C ++ любого стандарта.C ++ просто никогда не включал VLA.Это ключевой момент, когда вам нужно понять, что C и C ++ - это два совершенно разных языка.Существуют допустимые программы на C, отличные от C ++ (например, foo()), и существуют допустимые программы на C ++, отличные от C (например, bar()).C ++ больше не является строгим надмножеством, с которого он начинал.

Тем не менее, компиляторы могут выбрать реализацию надмножества языка как расширения.g++ делает это, но если вы компилируете со строгим соответствием стандарту C ++ (g++ -std=c++14 -pedantic -Werror), даже g++ выдает ошибку на foo().

...