2009-10-21 5 views
11

Рассмотрим следующий код:Создание массива объектов в стеке и куче

class myarray 
{ 
    int i; 

    public: 
      myarray(int a) : i(a){ } 

} 

Как вы можете создать массив объектов MyArray в стеке, и как вы можете создать массив объектов в куче?

+0

Это вопрос домашней работы? Это звучит как один. – Amber

+0

Nope ... Это не вопрос о домашнем задании ... Нашел это в Интернете во время подготовки к собеседованию .... :) –

ответ

34

Вы можете создать массив объектов на стеке через:

myarray stackArray[100]; // 100 objects 

А на куче (или "FreeStore"):

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++ на самом деле не имеют "стек" или "кучу"/"FreeStore". У нас есть время «автоматического хранения» и «динамического хранения». На практике это выравнивается с распределением стека и распределением кучи.

†† Если вам требуется «динамическое» выделение из стека, вам нужно определить максимальный размер (хранилище стека известно заранее), а затем дать вектору новый распределитель, чтобы вместо этого использовать стек.

+0

вы можете использовать '_alloca()' для динамического выделения переменных сумм памяти в стеке ... – Crashworks

+0

@GMan - это нестандартная, но широко распространенная функция C. –

+2

Он работает аналогично в C++, что он делает в C; если есть более стандартный способ сказать компилятору выделить N байтов в стеке, где N определяется во время выполнения, я не знаю, что это такое. – Crashworks

2

Если вы создаете массив объектов класса myarray (либо на стеке, либо на куче), вам нужно будет определить конструктор по умолчанию.

Невозможно передать аргументы конструктору при создании массива объектов.

0

Я знаю, как создать объект с из конструктора по умолчанию, но только на стеке:

Предположим, вы хотите создать 10 объектов для MyArray класса с a = 1..10:

MyArray objArray[] = { MyArray[1], MyArray[2]......MyArray[10]} 

Нет необходимости называть деструктор, потому что они созданы в стеке.

+1

Синтаксис? Используйте круглые скобки, следующее использование timearie: MyArray objArray [] = {MyArray (0), MyArray (88) и т. Д.} – Hoven

+0

Как уже упоминалось, это не скомпилировалось. –

-1
#include <stdio.h> 
class A 
{ 
public: 
    A(int a){ 
     printf("\nConstructor Called : %d\n",a); 
     aM = a; 
     } 
    ~A(){ 
    printf("\ndestructor Called : %d\n",aM); 
} 
private: 
    int aM; 
}; 

int main() 
{                         
    A **a = new A*[10]; 
    for (int i = 0;i<10;i++) 
    a[i] = new A(i+1); 
    for (int i = 0;i<10;i++) 
     delete a[i];// = new A(i+1);                      

    delete []a; 
} 
+0

Это половина кучи ... –

+0

Я также не вижу, где есть какой-либо массив из A, если только объекты не считаются массивами размера 1. –

3

Так как 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() { ... } 

Есть также варианты, чтобы использовать Кассиопеяне VLAs или C++ с new, но вы должны воздерживаться от их использования как можно больше, поскольку их использование делает код подверженным ошибкам сегментации и утечкам памяти.

+0

'std :: array' хорош, потому что, как и любая другая хорошо запрограммированная обертка вокруг «T [n'] - он знает свой собственный размер (с помощью шаблонной магии), может быть передан более приятным образом, может быть возвращен из функций и т. д. Мне понравилось« вы никогда не знаете, когда переполняете стек », - ну, за исключением случаев, когда он вызывает полностью случайное повреждение памяти без стека и делает себя очень очевидным :-), но, конечно, лучше избегать выделения огромных массивов в стеке. –

Смежные вопросы