为什么这会引发SIGSEGV? (堆分配的std :: array)

问题描述 投票:0回答:1

我正在寻找构建一维std::array结构,每个结构的大小为16个字节。 1D数组是表示3D数组(基本上是std::array包装器,具有一些3D特定运算符和其他绒毛)的类的扁平化。我的第一个尝试是一个大小为256 x 256 x 32的数组,大约为35MB,这会引发SIGSEGV错误。

所有内容的简化示例如下:

Structs.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在堆上分配此结构。许多人(在此站点和其他站点上)说:“即使在堆上,要查找大范围的[[contiguous内存也很困难”,但并未给出合理的预期。记忆是。我认为现代计算机中32MB是可行的。

可能会抛出一个段。这里有问题吗?
c++ arrays segmentation-fault heap
1个回答
1
投票
ArrayWrapper<MyStruct, HSIZE, VSIZE> coords = *coords_;
应该是...

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

...这很有意义。第一行正在复制coords_'引用,在这种情况下,由于使用了new,因此该副本已放在堆栈中。 
© www.soinside.com 2019 - 2024. All rights reserved.