2014-11-13 3 views
3

Я пытаюсь написать класс для хранения миллионов данных 3D-координат. Во-первых, я попытался использовать 3D-массив для хранения данных координат.Могу ли я объявить очень большой массив в классе, C++

#ifndef DUMPDATA_H 
#define DUMPDATA_H 
#define ATOMNUMBER 2121160 
#include <string> 
using namespace std; 
class DumpData 
{ 
public: 
    DumpData(string filename); 
    double m_atomCoords[ATOMNUMBER][3]; 
}; 
#endif // DUMPDATA_H 

Затем я составил программу, но я получил, когда я ошибку сегментации запустить программу в Ubuntu 14.04 системы (64 бит). Поэтому я изменил 3D-массив на вектор, объявив:

vector < vector <double> > m_atomCoords; 

Тогда программа работала. Мне просто интересно, существуют ли ограничения в объявлении очень больших массивов в классе?

+0

48mb не так уж много, если вы не объявляете нестатистическую локальную переменную, тогда вы, скорее всего, закончите пространство стека. –

+0

@CaptainObvlious 8mb? '2121160 * 8 * 3/1024/1024' дайте мне 48 –

+0

@BryanChen Просто пропустил 4 при наборе текста. К сожалению. –

ответ

6

В общем, стек имеет ограниченный размер.

Это, вероятно, вызвать переполнение стека:

int main() { 
    DumpData x; 
} 

Хотя это не будет:

int main() { 
    static DumpData x; 
    std::unique_ptr<DumpData> y = std::make_unique<DumpData>(); 
} 
2

Стек является очень ценным и дефицитным ресурсом, поэтому я бы просто использовать куча для выделения больших данных.

Если у вас есть массив 3D-координаты, вместо того, чтобы использовать vector<vector<double>>, я бы просто определить класс для представления 3D-точки, используя только три отдельных double элементов данных, или массив из трех double с сырой , например:

class Point3D { 
private: 
    double m_vec[3]; // X, Y and Z 

    // or: 
    // double x; 
    // double y; 
    // double z; 

public: 
    double X() const { 
    return m_vec[0]; 
    // or: 
    // return x; 
    } 
    ... other setters/getters, etc. 
}; 

, и тогда я бы просто использовать std::vector<Point3D> в качестве элемента данных внутри вашего DumpData класса.

(A Point3D класса, определенные как указано выше, имеет меньше накладные расходы, чем std::vector<double>, а также предлагает более высокий уровень семантики, так что это лучший выбор.)

С распределителем по умолчанию, std::vector будет выделять память для огромное количество Point3D s от куча (не из стека), который хорошо работает, и он также скрыт от клиента DumpData, что делает приятный простой публичный интерфейс для класса DumpData.