Массивы, созданные в функциях, во время компиляции или во время выполнения?

Когда мы создаем массив в стеке, большинство компиляторов захотят узнать размер массива, который будет определен во время компиляции, поэтому обычно мы не можем заставить пользователя ввести размер массива из стандартного ввода, но что, если мы вызываете функцию, и мы передаем это число, введенное пользователем, в функцию для создания массива?

разве эта функция не вызывалась во время компиляции?

например, если пользователь вводит 1, разве эта функция не вызывается во время выполнения? Так как пользователь будет определять, будет ли вызываться функция.

или это еще время компиляции?

#include <iostream>

void someFunction(int number){

    int sampleArray[number];

    for(int i = 0; i < number; i++){

        sampleArray[i] = 0;
    }
    // I know what I'm doing is pointless but is it possible?
}

int main()
{
   int number = 0;
   int choice = 0;

   std::cout << "do you want to create an array? press 1 for yes" << std::endl;
   std::cin >> choice;
   if (choice == 1){

   std::cout << "enter size" << std::endl;
   std::cin >> number;

   someFunction(number);

   }
}

Во время компиляции ничего не вызывается.

Scott Hunter 28.05.2018 23:22

с return sampleArray; вы возвращаете адрес локальной переменной и, следовательно, висячий указатель.

Jarod42 28.05.2018 23:26

очень хороший момент

strikeforcefan2013 28.05.2018 23:32
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
702
5

Ответы 5

То, что вы используете, называется массивом переменной длины. Он не является частью стандарта C++, но некоторые компиляторы поддерживают его как расширение.

Чтобы ваш код соответствовал стандарту, не используйте его. Вместо этого используйте std::vector<int>.

std::vector<int> someFunction(int number){

    std::vector<int> sampleArray(number);

    // No need for this. sampleArray elements are zero initialized.
    /*
    for(int i = 0; i < number; i++){
        sampleArray[i] = 0;
    }
    */
    return sampleArray;
}

number не является значением constexpr.

Итак, int sampleArray[number]; все еще недействителен C++ и является расширением VLA.

В случае, который вы показываете, в C (и большинстве компиляторов C++) пространство для массива зарезервировано в стеке при вызове функции.

Точно так же вы можете сделать это вручную, используя такие функции, как alloca().

VLA и alloca () не являются частью C++.

user2100815 28.05.2018 23:46

Что вы делаете, так это создаете массив переменной длины, что обычно является плохой практикой, если вы хотите создать свой массив статически, лучше дать ему значение фиксированной длины, иначе, если вам остро нужна переменная длина array, вы можете использовать динамическое размещение для создания вашего массива или вы можете использовать векторы из STL.

Это не только плохая практика, это недопустимо в C++.

user2100815 28.05.2018 23:44

Думаю, правильнее было бы назвать это динамическим управлением памятью. Также я очень сомневаюсь, что приведенный вами пример кода будет работать правильно. Например:

int sampleArray[number]; 

Также вызовет ошибку во многих компиляторах, и в конечном итоге вы все равно получите предупреждение в других компиляторах.

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

int size;
std::cin >> size;
int * array = new int[size];

Это будет работать в любом известном мне компиляторе и не вызовет предупреждений. Но вы должны иметь в виду, что вам придется удалить память, когда вам больше не нужен массив. Например, когда он вот-вот выйдет за рамки.

delete []array;

Начиная с C++ 11 вы можете использовать умный указатель. Они позаботятся о памяти массива вместо вас и удалят память.

int size;
std::cin >> size;
std::shared_ptr<int[]> array(new int[size]);

То же самое можно сделать с unique_ptr и так далее. Во многих случаях будет достаточно просто использовать std :: vector для любого хранилища типа int.

Предпочитайте std::unique_ptrstd::shared_ptr, потому что вы всегда хотите использовать самое узкое и строго регулируемое решение. Для этой задачи лучше обоих std::vector.

user4581301 29.05.2018 00:13

Другие вопросы по теме