Почему это выбрасывает SIGSEGV? (Выделенная куча std :: array) - PullRequest
0 голосов
/ 02 апреля 2020

Я собираюсь построить 1D std::array структур, каждая из которых имеет размер 16 байтов. 1D-массив - это уплощение класса, представляющего 3D-массив (в основном оболочку std::array, в которой есть некоторые операторы 3D-спецификаций c и другие пух). Моя первая попытка - это массив размером 256 x 256 x 32, примерно 35 МБ, который выдает ошибку SIGSEGV.

Упрощенный пример всего выглядит следующим образом:

Структуры. cpp

struct Coord {
    int x;
    int y;
    int z;
    Coord() { }
    Coord(int x_, int y_, int z_) { x = x_; y = y_; z = z_; }
}

int TR (int arg) { 
    // ... Some transformation 
} 

struct MyStruct {
    Coord position;
    int terrain;

    MyStruct() { }
    MyStruct(int x_, int y_, int z_, int terrain_) { 
        terrain = terrain_;
        position = Coord(TR(x_), TR(y_), TR(z_));
    }
}

ArrayWrapper.hpp

#include <array>

template <typename T, int HSIZE, int VSIZE> struct ArrayWrapper { 
    private:
        std::array<T, HSIZE*HSIZE*VSIZE> narray;

    public:
        void set(T obj, int x, int y, int z) {
            narray[x + z*HSIZE + y*HSIZE*HSIZE] = obj;
        }

        T& operator() (int x, int y, int z) {
            return narray.at(x + z*HSIZE + y*HSIZE*HSIZE);
        }

CoordinateMap. cpp

#include "ArrayWrapper.hpp"
#include "Structs.cpp"

const int HSIZE = 256;
const int VSIZE = 32;

class CMap {
    private: 
        ArrayWrapper<MyStruct, HSIZE, VSIZE>* coords_ = new ArrayWrapper<MyStruct, HSIZE, VSIZE>;
        ArrayWrapper<MyStruct, HSIZE, VSIZE> coords = *coords_;

    public:
        // ... Getter, setter, and a bunch of other methods, 
        ~CMap() { delete coords; }
}

Если я где-нибудь попытаюсь сказать CMap something;, я получу SIGSEGV. Я знаю, что стек относительно невелик, поэтому я пытаюсь выделить эту структуру в куче, используя new. Многие люди (на этом и других сайтах) говорят: «Найти большой диапазон памяти смежных трудно, даже если она находится в куче», но не дают указаний на то, что разумные ожидания относительно размера смежной памяти есть. Я думаю, что 32 МБ в современном компьютере выполнимо.

Что может быть броском сега. вина здесь?

1 Ответ

2 голосов
/ 02 апреля 2020
ArrayWrapper<MyStruct, HSIZE, VSIZE> coords = *coords_;

Должно быть ...

ArrayWrapper<MyStruct, HSIZE, VSIZE>& coords = *coords_;

... что имеет смысл. В первой строке создается копия ссылки coords_ ', которая в данном случае не использует цель использования new, поскольку эта копия помещается в стек.

...