как я могу объявить массив с переменной длиной, определенной во время выполнения на C++?

StackOverflow https://stackoverflow.com/questions/1079288

  •  21-08-2019
  •  | 
  •  

Вопрос

Пожалуйста, проверьте этот код, он компилируется и работает абсолютно нормально.Вопрос в том, что когда я начал изучать С++ (турбо С++), я никогда не мог объявить массив любого типа как ..

datatype var[variable_set_at_runtime];

и я считал само собой разумеющимся, что это невозможно в последних компиляторах gcc... но, как ни странно, это возможно...

Итак, мой сопутствующий вопрос заключается в том, зачем тогда нужен новый оператор??

Я знаю, что новый оператор делает много вещей, включая динамическое выделение памяти во время выполнения в куче, возврат адреса этому ресурсу... и т.д.

Какая разница, которую я чувствую, заключается в том, что мой код динамически распределяет память в стеке, а новый - в куче??это единственная разница...

я очень удивлен после написания чего-то подобного, поскольку я не мог этого сделать, когда начал изучать C++, и... чтобы добавить к этому, я могу сделать это и для пользовательских типов данных...:-О

#include<iostream>
using namespace std;
struct A
{
    int a;
    int b;
};
int main()
{
    int a;
    cin>>a;
    int ch[a];
    for(int i=0;i<a;i++)
        ch[i]=i+1;
    for(int i=0;i<a;i++)
        cout<<"\n\nch=="<<ch[i];
    A obj[a];
    cin>>obj[a-1].a;
    cin>>obj[a-1].b;
    cout<<"\n\n obj.a,obj.b=="<<obj[a-1].a<<" , "<<obj[a-1].b;
}

Пожалуйста, пролейте свет..

Спасибо.

Это было полезно?

Решение

И я считал само собой разумеющимся, что это не может быть возможно в последних компиляторах GCC ... но удивительно, что это возможно ...

Это разрешено в C, но не в C++.GCC может разрешить это в зависимости от флагов компилятора, но если вы компилируете свой код как строгий C++ (что вам и следует делать), массивы динамической длины не допускаются, и вам придется использовать new.(Удивлен, что никто еще не упомянул об этой маленькой детали)

Помимо этого, есть еще два больших различия:

  • данные в стеке автоматически очищаются, когда они выходят за пределы области видимости
  • для стека обычно выделяется около 1 МБ.Вместо этого большие структуры данных должны помещаться в кучу.

Но на самом деле самым важным моментом является первый — он недопустим в C++.(И, как заметил Нил, это также неверно и в C++0x.Планов по добавлению этого в C++ нет)

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

Вы должны выделить его в куче, используя новый :

int* ch = new int[ a ];

но не забудьте освободить его после использования:

delete [] ch;

Лучшим способом было бы использовать станд::вектор это делает именно то, что вы хотите.

Вы бы использовали новый:

datatype *var=new [variable_set_at_runtime];

а затем удалите его, когда закончите:

delete[] var;

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

Я бы предпочел использовать STL для обработки такого рода вещей, например, списка.

Таким образом, вам не придется самостоятельно управлять памятью, и код будет выглядеть аккуратнее.

посмотрите здесь руководство: http://www.sgi.com/tech/stl/

Стек — это очень маленький объем памяти.Вам следует размещать в стеке только небольшие временные вещи.Большие или временные объекты лучше размещать в куче.

Да, это потребует тщательного управления памятью.

Вещи, выделенные «автоматически», исчезнут, когда выделение выйдет за рамки.Вещи, расположенные «в куче» с new не будет.

Любая переменная, объявленная так, как вы указали, помещается в стек.Как только он выйдет за рамки, он перестанет быть действительным.Однако если вы используете new для объявления своего массива, он будет размещен в куче и останется действительным до тех пор, пока вы не вызовете для него метод delete.

Вам все еще нужен new оператор для распределения объектов в куче, и это необходимо, если вы хотите, чтобы они выживали за пределами функции, в которой они созданы.

Стек часто гораздо более ограничен по размеру, чем куча, и мне бы хотелось увидеть связанный список (или любой коллекция, не являющаяся массивом) объектов, созданных с использованием метода объявления массива переменной длины :-)

Нет, я думаю new может быть здесь еще немного.

«Какая разница, которую я чувствую, заключается в том, что мой код динамически распределяет память в стеке, а новый — в куче?это единственная разница..."

Именно в этом разница.Просто помни.Стек имеет ограниченное пространство, тогда как куча не имеет никаких ограничений (ну, очевидно, у него есть некоторые ограничения...попробуйте выделить 4 гигабайта для одного ;)).В общем, я говорю, что если вы знаете, что выделение вашего стека будет относительно небольшим, используйте свой метод, в противном случае создайте его в куче.

Используйте _alloca.Смотрите мой ответ здесь для Массивы переменного размера в C

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top