как я могу объявить массив с переменной длиной, определенной во время выполнения на C++?
-
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