2013-12-01 8 views
1

У меня есть класс, и я собираюсь объявить размер массива (двумерный) на основе ввода от пользователя. так:Объявление массива объектов в куче с переменным размером массива

class myClass {/*...*/} 

int main(){ 
myClass* arrayObj = new myClass[100][100]; 

Это прекрасно работает, и он должен поместить массив в куче. Но мне нужно сделать:

int arraySize; 
cin >> arraySize; 
myClass* arrayObj = new myClass[arraySize][arraySize]; 

Я получаю сообщение об ошибке: «ARRAYSIZE» не может появиться в постоянной экспрессии.

Я предполагаю, что это означает, что я могу иметь только константы в объявлении массива, но если нет, то как я могу это сделать? Массив слишком большой, чтобы поместиться в стеке, поэтому я делаю это в куче в первую очередь.

Редактировать: У меня есть работа с указателями, но у меня другая проблема, у меня есть функция, которая использует массив, т.е.

void myFunction() 
{ 
    /*...*/ 
    arrayObj[something][something].variable = somethingElse // error here 
} 

int main() 
{ 
    /*...*/ 
    int arraySize; 
    cin >> arraySize; 
    MyClass **arrayObj = new MyClass*[arraySize] 
    for (int i = 0; i < arraySize; i++) arrayObj[i] = new MyClass[arraySize] 
    /*...*/ 
} 

Я получаю: ошибка: «arrayObj» не был объявлен в этой области. Я могу понять, почему, но это на куче, и это указатель, разве это не глобально? Если нет, как бы я сделал это глобальным?

+1

Это очень важно: http://stackoverflow.com/questions/1887097/variable-length-arrays-in-c – supertopi

+2

Вы должны взглянуть на ['std :: vector'] (http: // en .cppreference.com/w/cpp/container/vector) –

+0

«Это прекрасно работает ...» - нет, это не так. Ваш компилятор ужасно мягкий. Вы присваиваете 'myClass (*) [100]' указателю типа 'myClass *'. Это не тот же тип, и повышенный уровень предупреждения от вашего компилятора, скорее всего, скажет вам об этом (и не с ошибкой, если предупреждения настроены на сбой, но он должен * быть ошибкой независимо, и я бы подумал об утилизации вашей инструментальной цепочки если это не так). Это должно также рассказать вам о том, почему ваш второй фрагмент также потерпит неудачу. – WhozCraig

ответ

2

Прежде всего, вы ошибаетесь говорят, что это

class myClass {/*...*/} 

int main(){ 
myClass* arrayObj = new myClass[100][100]; 

работает отлично. Компилятор выдает ошибку, потому что не существует неявное преобразование из MyClass (*) [100], чтобы MyClass *

Как для вашей проблемы, то вы должны использовать следующий подход:

myClass **arrayObj = new myClass *[arraySize]; 

for (int = 0; i < arraySize; i++) arrayObj[i] = new myClass[arraySize]; 
+0

Это сработало, спасибо. Можете ли вы объяснить первую строку? Что означают все звездочки? – user3055201

0

Если вы должны использовать массивов, тогда другой способ обойти это наложить ограничение на количество элементов в массиве и убедиться, что этот предел применяется в вашем коде. Это один из недостатков использования массивов против std :: векторов. Массивы представляют собой фиксированный размер, в то время как векторы могут динамично развиваться. Кстати, что вы подразумеваете под «Массив слишком велик, чтобы вписаться в стек, поэтому я делаю это в куче в первую очередь». Если он слишком велик, чтобы поместиться в стеке, то, возможно, нам стоит посмотреть, почему массив настолько велик. Возможно, есть лучший способ решить любую проблему, с которой вы пытаетесь справиться.

+0

Это «игра жизни», пользователь вводит размер сетки, программа, похоже, падает с любым входом более 300 (помните, что это квадрат, так что это довольно большой массив). – user3055201

2

C++ на самом деле не имеет встроенной модели многомерных массивов переменного размера. Только внешнее измерение может меняться во время выполнения, все остальные измерения фиксированы. Фон - это то, как C++ выполняет арифметику: при добавлении смещения к указателю он увеличивается по размеру объекта со статически определенным размером.

Если вы хотите, чтобы многомерный массив изменялся в других измерениях, вам нужно будет использовать подходящий класс или реализовать его самостоятельно (стандартная библиотека C++ имеет std::valarray<T> для сортировки сделок с многомерными массивами, но их использование, скажем, не совсем прямолинейно). Самый простой способ - использовать, возможно, std::vector<std::vector<myClass> >.

Более эффективный подход состоит в том, чтобы выделить большой std::vector<myClass> в качестве члена класса и иметь operator[]() для этого класса, возвратить представление в соответствующий раздел этого массива. Для начала я бы, вероятно, просто использовал std::vector<std::vector<myClass> >, завернутый в класс, и изменил реализацию, если окажется, что он слишком неэффективен.

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