2015-06-23 2 views
0

Я использую это, чтобы выделить 2D массив в CPP:ограничение по размеру в C++?

int s[n][2]; 

но мне кажется, что при п очень большой (до 1Е6), это создает ошибку времени выполнения (ExitCode: 11).

Как решить эту проблему?

+4

Это не динамическое распределение. – Mysticial

+0

В глобальном масштабе или в функции (в этом случае у вас заканчивается стека)? – usr2564301

+0

Я сделал ошибку.Я попытался избежать динамического выделения, например new int [], поэтому использовал это. Так что теперь это не динамика. – ssd

ответ

1

Этот тип декларации выделяет память в стеке. Это, вероятно, слишком велико. Используйте динамическое распределение REAL (new int[n]).

+0

В чем разница между этим методом и новым int []? – ssd

+0

Если «* этот метод *» вы имеете в виду ваш исходный код, то разница, как я уже сказал, заключается в том, что ваш код пытался выделить память в стеке, и это слишком велико. – Amit

3

Вы выделяете на стек, и вы получаете переполнение стека.

Вы должны выделить ваш 2d массив как этот

int** ary = new int*[sizeY]; 
for(int i = 0; i < sizeY; ++i) 
ary[i] = new int[sizeX]; 

См How do I declare a 2d array in C++ using new?

Или еще лучше, использовать Boost::ublas::matrix или Eigen Vector2d, или как Пол МакКензи предложил использовать std::vector (самый простой из них всех)

+0

Если я использую это и говорю, что хочу передать ary какой-либо функции, как объявить параметр этой функции? Для int ary [n] [2] я могу сделать void f (int [] [2]), но как насчет этого? Это то же самое? – ssd

+0

Сделайте, как говорит Пол Маккензи, используйте 'std :: vector'. Это довольно просто использовать. Для перехода к функции перейдите по ссылке на const. Просто прочитайте об этом, вы увидите. Если вам нужно обновить массив 2d, перейдите по ссылке. –

+0

@ssd вы можете передать его как 'void func (int ** ary)', но будьте осторожны, чтобы вы потеряли всю информацию о размерах. Вы знаете, где находится ary в памяти, но не имеют понятия, насколько это велико, если вы также не пропустите его. – user4581301

3

Это не динамическое распределение. Кроме того, если n - это переменная, она даже не действительна ANSI C++, поскольку вы не можете объявлять массивы с переменным количеством записей.

Чтобы правильно распределить динамически, рассмотрите возможность использования std::vector.

#include <vector> 
//... 
// Simulate s[n] 
std::vector<std::vector<int>> s(n, std::vector<int>(2)); 
//.. 
// You can now use s similar to a 2 dimensional array. 

Если по какой-то причине вам требуется данные должны быть смежными для 2-й массив, рассмотрим ответы здесь:

how to create a contiguous 2d array in c++?

+0

Я занимаюсь практическими проблемами, STL запрещен. Поэтому я не могу использовать этот метод. – ssd

+1

'n' может быть переменной, если она' const'. – NathanOliver

+0

Также обратите внимание на реализацию Boost.MultiArray (http://www.boost.org/doc/libs/1_58_0/libs/multi_array/doc/user.html). Это немного сложнее, но также должно быть довольно образовательным. –

1

Как другой сказал, «проблема» вы «у вас есть, потому что вы не используете распределение динамической памяти.

@ {Straight Line} показал вам C-образное решение для создания 2d массивов, а @PaulMcKenzie показал вам один, используя векторы, и поднял вопрос о непрерывном хранении. Однако последнее отличается тем, что оно не ограничивает размер столбцов (при условии индексации [row][col]).

The answer @dasblinkenlight показывает вам, как создать свой собственный класс массива 2d; Я думаю, что в этом суть C++, чтобы определить, как вы собираетесь управлять памятью, и предоставить набор общедоступных методов для взаимодействия с этим «объектом» в вашем коде. 2-мерный массив размером n x p - это не что иное, как np элементы, индексированные двумя индексами, так что это то, что вы должны кодировать. Здесь близко к минимальному пример того, как сделать это:

#include <new> 

template <class T> 
class Array2D 
{ 
public: 

    Array2D() 
     : m_ptr(NULL) 
     { clear() } 
    ~Array2D() 
     { clear(); } 

    void clear() 
    { 
     // free current allocation if any 
     if (m_ptr) 
      delete[] m_ptr; 

     // reset member variables 
     m_ptr = NULL; 
     m_nrows = m_ncols = 0; 
    } 

    inline unsigned nrows() const { return m_nrows; } 
    inline unsigned ncols() const { return m_ncols; } 

    void set_size(unsigned nr, unsigned nc) 
    { 
     // clear any previous allocation 
     clear(); 

     // new allocation 
     m_ptr = new T[nr*nc]; 
     m_nrows = nr; 
     m_ncols = nc; 
    } 

    // access elements using [row][col] 
    inline T* operator[] (unsigned row) 
     { return &m_ptr[ row*n_cols ]; } 

    // access elements using (row,col) 
    inline T& operator() (unsigned r, unsigned c) 
     { return m_ptr[ c + n_cols*r ]; } 

protected: 

    T *m_ptr; 
    unsigned m_nrows, m_ncols; 
}; 

Если вы знаете, что вы собираетесь использовать матрицы много, хотя, ваш первый рефлекс должен проверить, что уже существует. Существует много зрелых библиотек C++, которые реализуют 2d массивы (см., Например, this comparison), которые касаются функций, проблем и оптимизаций, которые вы не хотите пересматривать самостоятельно (если вы действительно не знаете, что делаете, или вам действительно нужно что-то простое) , Вам просто нужно найти библиотеку, которая соответствует вашим потребностям для каждого конкретного приложения.

+1

Если вы хотите уточнить это, я предлагаю перейти к примеру «grid» в этой главе - http://web.stanford.edu/class/cs106l/course-reader/Ch10_OperatorOverloading.pdf –

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