Рассмотрим следующий код:
class myarray
{
int i;
public:
myarray(int a) : i(a){ }
}
Как вы можете создать массив объектов myarray в стеке и как вы можете создать массив объектов в куче?
Рассмотрим следующий код:
class myarray
{
int i;
public:
myarray(int a) : i(a){ }
}
Как вы можете создать массив объектов myarray в стеке и как вы можете создать массив объектов в куче?
Вы можете создать массив объектов в стеке† с помощью:
myarray stackArray[100]; // 100 objects
И в куче† (или "свободном хранилище"):
myarray* heapArray = new myarray[100];
delete [] heapArray; // when you're done
Но лучше не управлять памятью самостоятельно. Вместо этого используйте std::vector:
#include <vector>
std::vector<myarray> bestArray(100);
Вектор — это динамический массив, который (по умолчанию) размещает элементы из кучи.††
Поскольку у вашего класса нет конструктора по умолчанию, чтобы создать его в стеке, вам нужно сообщить компилятору, что передать в конструктор:
myarray stackArray[3] = { 1, 2, 3 };
Или с вектором:
// C++11:
std::vector<myarray> bestArray{ 1, 2, 3 };
// C++03:
std::vector<myarray> bestArray;
bestArray.push_back(myarray(1));
bestArray.push_back(myarray(2));
bestArray.push_back(myarray(3));
Конечно, вы всегда можете дать ему конструктор по умолчанию:
class myarray
{
int i;
public:
myarray(int a = 0) :
i(a)
{}
};
† Для педантов: C++ на самом деле не имеет «стека» или «кучи»/«свободного хранилища». У нас есть продолжительность «автоматического хранения» и «динамического хранения». На практике это согласуется с выделением стека и выделением кучи.
†† Если вы хотите «динамическое» выделение из стека, вам нужно определить максимальный размер (хранилище стека известно заранее), а затем указать вектору новый распределитель, чтобы вместо этого он использовал стек.
_alloca()
для динамического выделения переменных объемов памяти в стеке...
- person Crashworks; 21.10.2009
vector
указывает, что элементы будут в куче. например, классическая реализация string
сохраняет символы внутри самого объекта до 8 или 16 символов в целом. затем, когда ему нужно удлиниться, он переключается на кучу. Итак, если сам объект string
находится в стеке, данные также находятся в стеке для всех строк меньше 16. Можно представить, что вектор может действовать одинаково в реализациях, нет?
- person v.oddou; 24.02.2015
Поскольку C++11 std::array<T,size>
доступен для массивов, размещенных в стеке. Он обертывает T[size]
, предоставляя интерфейс std::vector
, но большинство методов - constexpr
. Недостатком здесь является то, что вы никогда не знаете, когда переполняете стек.
std::array<myarray, 3> stack_array; // Size must be declared explicitly.VLAs
Для массивов, выделенных с помощью динамической памяти, используйте std::vector<T>
. Если вы не укажете пользовательский распределитель, стандартная реализация будет использовать память кучи для выделения элементов массива.
std::vector<myarray> heap_array (3); // Size is optional.
Обратите внимание, что в обоих случаях для инициализации массива требуется конструктор по умолчанию, поэтому вы должны определить
myarray::myarray() { ... }
Существуют также варианты использования VLA C или new
C++, но вам следует воздерживаться от их использования. насколько это возможно, потому что их использование делает код подверженным ошибкам сегментации и утечкам памяти.
std::array
хорош тем, что - как и любая другая хорошо запрограммированная оболочка вокруг T[n
] - он знает свой собственный размер (с помощью магии шаблонов), может быть передан более приятным образом, может быть возвращен из функций и т. д. Вы мне понравились никогда не знаешь, когда вы переполняете стек - ну, за исключением случаев, когда это вызывает совершенно случайное повреждение нестековой памяти и становится очень очевидным :-) но, конечно, лучше избегать выделения огромных массивов в стеке.
- person underscore_d; 15.02.2016
Если вы создаете массив объектов класса myarray (либо в стеке, либо в куче), вам нужно будет определить конструктор по умолчанию.
Невозможно передать аргументы конструктору при создании массива объектов.
Я знаю, как создать объект из конструктора по умолчанию, но только в стеке:
Предположим, вы хотите создать 10 объектов для класса MyArray с a = 1..10
:
MyArray objArray[] = { MyArray[1], MyArray[2]......MyArray[10]}
Не нужно вызывать деструктор, потому что они создаются в стеке.