从引用的Vector获取SEGFAULT

Dyl*_*dds -2 c++ vector segmentation-fault sfml

问题:

所以,我一直在撞墙挡在头上.我有一个在OSX和Linux上编译并运行良好的应用程序,但是当我使用MingW64在Windows上编译它时,我在运行时获得了一个SEGFAULT.所以这就是发生的事情;

我有一个包含的Map类std::vector<Tilesheet*> m_tilesheets.我通过引用构造函数将此变量传递给另一个类MapLayer:

    MapLayer::MapLayer(std::vector<unsigned int>& p_data,
                   std::vector<MindTrip::Graphics::TileSheet*>& p_tilesheets)
        : m_data(p_data),
          m_tilesheets(p_tilesheets)
{
    DrawTexture();
}
Run Code Online (Sandbox Code Playgroud)

矢量存储为MapLayerClass中的引用, std::vector<MindTrip::Graphics::TileSheet*>& m_tilesheets;

如果我在该构造函数的第一行放置断点,则m_tilesheets具有_M_First的定义值.如果我在构造函数的最后一行放置一个断点,则m_tilesheets不再具有_M_First的定义值.我没有进行多线程处理,并且应用程序还没有离开这些变量定义的范围.

在它的下一个函数中DrawTexture(),有一个foreach循环遍历m_tilesheets,它不断给我一个SEGFAULT:

void MapLayer::DrawTexture() {
    for(unsigned int tile_val: m_data)
    {
        // SEGFAULT ON THIS LINE
        for(MindTrip::Graphics::TileSheet* tileSheet : m_tilesheets)
        {

        }
    }
}`
Run Code Online (Sandbox Code Playgroud)

这是我尝试过的:

我已经尝试将其转换为常规for循环,但仍然会遇到同样的问题.

我尝试使用引用通过将foreach循环转换为向量来抓取向量中的对象: for(auto& tileSheet : m_tilesheets).同样的问题

如果我将m_tilesheets移出MapLayer类及其构造函数并将其作为参数传递给DrawTexture作为参考:

MapLayer::DrawTexture(std::vector<MindTrip::Graphics::TileSheet*>& p_tilesheets)

M_data开始在其foreach循环中抛出段错误.这很奇怪,因为m_data的foreach循环实际上发生在m_tilesheet之前的行上:for(unsigned int tile_val: m_data)

所以,为了回应这个问题,我尝试将m_data移动到DrawTexture的参数并将其作为成员删除,就像我为m_tilesheets所做的那样,通过引用传递:

MapLayer::DrawTexture(std::vector<MindTrip::Graphics::TileSheet*>& p_tilesheets, std::vector<unsigned int>& p_data)

当我尝试这个时,我使用for循环而不是foreach.p_tiles表中应该有1个条目,p_data中应该有10000个条目.这次segfault抛出了我访问p_tilsheet数据的行,p_tilesheet[j]; j并没有超出范围并被设置为0.

尝试了所有这些之后,我将代码重置回原来的样本,而不是决定使用std :: copy()来复制向量中的数据,而不是使用类中的引用,我只是实例化了新的变量对于m_tilesheets和m_data.我将foreach切换回常规for循环,然后再次获得段错误访问m_tilesheets的元素[j].

我对你的记忆甚至发生了什么感到困惑.m_tilesheets和m_data在被访问时不为null,并且甚至在构造函数结束之前,它们的_M_First属性也会以某种方式取消设置.

再一次,只发生在Windows上.OSX和Linux工作正常.在我实现map类之前,应用程序在windows上正常运行.不只是寻找修复作为答案,而是发生错误的原因.

编辑:

这是Map的构造函数,我在这里定义这些值并将它们传递给MapLayer的新实例.

Map::Map(const char* p_map_file)
{
         m_tile_sheets.push_back(new MindTrip::Graphics::TileSheet("PathToTilesheet", 0));

        std::vector<unsigned int> data(10000, 50);
        m_layers.push_back(new MapLayer(data, m_tile_sheets));
}
Run Code Online (Sandbox Code Playgroud)

gor*_*kic 5

您提供的代码中没有出现您的问题.这段代码只是触发了bug.另外(正如其他人也指出的那样),你的代码在Linux和OSX上运行不正常,它只是没有出现这个bug.

既然你也在Linux上编译,我建议你通过valgrind运行你的代码,并扫描输出未初始化的变量,缓冲区溢出等...要启动它,你可以使用以下代码:

valgrind --tool=memcheck --track-origins=yes --log-file=log.txt your_prog arg arg
Run Code Online (Sandbox Code Playgroud)

在完成tun后,您将检查包含在log.txt中的(大量)数据.你的问题几乎肯定会出现.

除此之外,我会问你为什么使用原始指针?如果你没有很好的理由,我会建议使用别的东西(例如TileSheets/MapLayers的智能指针,std :: string而不是char*).裸指针是创建这种错误的"最快捷方式".