【问题标题】:Access violation writing location when push_back() in a C++ vector?在 C++ 向量中 push_back() 时访问冲突写入位置?
【发布时间】:2013-11-16 14:51:51
【问题描述】:

背景信息

当“访问冲突写入位置 0x00000008”被抛出时,我正在编辑源代码的完全不同的部分。对象加载之前一直在工作,而我在错误编译之前修改的部分位于完全不同的类中。

更多积分

  • 退出程序时,我不断收到“堆损坏”错误,但我没有修复它。
  • 在编译有缺陷的版本之前,我对源代码所做的唯一编辑是我向另一个与对象加载无关的公共类添加了 2 个新向量。是内存不足还是怎么回事?

最小化的“ObjectHandler.hpp”

#include "Object.hpp"
#include "SFML/System.hpp"
#include "SFML/Network.hpp"

struct objtex
{
    sf::Int32 id;
    sf::Texture* tx;
};

class ObjectHandler
{
    private:
        std::vector< std::vector < std::vector< Object* > > > objects;
        std::vector<objtex> textures;

    public:
        void loadTextures();
};

最小化的“Object Handler.cpp”

void ObjectHandler::loadTextures()
{
    bool stillLoading = true;
    sf::Int32 id = 0;
    while(stillLoading)
    {
        std::stringstream ss;
        ss << "rsc/Objects/" << id << ".png";

        sf::Image i;
        if(i.loadFromFile(ss.str()))
        {
            i.createMaskFromColor(sf::Color(255, 0, 255));

            objtex o;
            o.id = id;
            o.tx = new sf::Texture;
            o.tx->loadFromImage(i);
            std::cout << "OOO";
            textures.push_back(o);      //  <<< THE PROBLEM >>>
            std::cout << "PPP";

            id += 1;
        }

        else
        {
            stillLoading = false;
            std::cout << "exited";
        }
    }
}

编译结果

每当我从 Main.cpp 调用 loadTextures() 时,它都会在第二次循环后在 textures.push_back() 处引发错误。它第一次起作用。 This is what my console outputs.

还有these are all of the warnings that are thrown compile-time(在我遇到这些问题之前都没有出现)。

1>c:\users\brady\dropbox\dwell project\project\client\client\gamegui.cpp(2156): warning C4789: destination of memory copy is too small
1>c:\users\brady\dropbox\dwell project\project\client\client\gamegui.cpp(1923): warning C4789: destination of memory copy is too small
1>c:\users\brady\dropbox\dwell project\project\client\client\gamegui.cpp(1924): warning C4789: destination of memory copy is too small
1>c:\users\brady\dropbox\dwell project\project\client\client\objecthandler.cpp(261): warning C4715: 'ObjectHandler::getTexture' : not all control paths return a value
1>c:\users\brady\dropbox\dwell project\project\client\client\networkmanager.cpp(41): warning C4789: destination of memory copy is too small
1>c:\users\brady\dropbox\dwell project\project\client\client\actionhandler.cpp(226): warning C4715: 'ActionHandler::getActionName' : not all control paths return a value
1>c:\users\brady\dropbox\dwell project\project\client\client\game.cpp(19): warning C4789: destination of memory copy is too small
1>c:\users\brady\dropbox\dwell project\project\client\client\menu.cpp(487): warning C4789: destination of memory copy is too small
1>c:\users\brady\dropbox\dwell project\project\client\client\menu.cpp(585): warning C4789: destination of memory copy is too small
1>c:\users\brady\dropbox\dwell project\project\client\client\gamegui.cpp(1858): warning C4789: destination of memory copy is too small
1>c:\users\brady\dropbox\dwell project\project\client\client\gamegui.cpp(1859): warning C4789: destination of memory copy is too small
1>c:\users\brady\dropbox\dwell project\project\client\client\gamegui.cpp(607): warning C4789: destination of memory copy is too small
1>c:\users\brady\dropbox\dwell project\project\client\client\gamegui.cpp(612): warning C4789: destination of memory copy is too small
1>c:\users\brady\dropbox\dwell project\project\client\client\gamegui.cpp(837): warning C4789: destination of memory copy is too small
1>c:\users\brady\dropbox\dwell project\project\client\client\gamegui.cpp(838): warning C4789: destination of memory copy is too small
1>c:\users\brady\dropbox\dwell project\project\client\client\gamegui.cpp(848): warning C4789: destination of memory copy is too small
1>c:\users\brady\dropbox\dwell project\project\client\client\gamegui.cpp(855): warning C4789: destination of memory copy is too small
1>c:\users\brady\dropbox\dwell project\project\client\client\game.cpp(632): warning C4789: destination of memory copy is too small
1>c:\users\brady\dropbox\dwell project\project\client\client\networkmanager.cpp(879): warning C4789: destination of memory copy is too small

所有这些警告都将我带到代码中的随机位置——这些都与内存分配无关。都是完全随机的。例如:

Game::Game()
{
    windowPos = gl::Win.getPosition();

    sprinting = false;
    hit = false;
    hasFocus = true;
    dead = false;
    isChiefStaff = false;
    drawGUI = true;           //  <<<  WARNING POINTS HERE  >>> 
}

提前谢谢你!

更新

  • [11:04 11/16/2013] 我只是在调试模式下运行它,它指向我的 Game 类的开头,而不是 ObjectHandler 类。 Game 类是我通过添加 2 个新向量编辑的类。有趣的。它仍然会抛出同样的异常。

更新

  • [7:02 11/16/2013] 我修好了。我重建了解决方案并在删除后将所有指针设置为 NULL。这修复了堆上发生的所有损坏。感谢那些提供帮助的人。

【问题讨论】:

  • objtex 携带原始资源 - 指向 sf::Texture 的指针。它需要一个复制构造函数、一个赋值运算符和一个析构函数。搜索三法则。
  • 在程序中的某个地方,您正在覆盖堆分配的缓冲区。这会破坏堆。 vector&lt;&gt; 将在您添加项目时在堆上分配内存。所以你的问题是你在某个地方有堆损坏。堆损坏发生时通常不会导致崩溃,但下次访问堆时会导致崩溃。修复你的堆损坏。
  • 您应该将编译器警告作为文本复制到您的问题中,而不是发布屏幕转储。您还可以标记警告所抱怨的代码行(如果它在这里)。如果不是,您可以编辑您的问题并将代码放在这里,以便我们了解您在这些行中所做的事情。
  • @drescherjm 好的,我刚刚用更多信息编辑了 OP。
  • @Jungle - 如果你正在覆盖缓冲区的边界,你会得到 C 中所谓的“未定义行为”。由于行为未定义,您的代码可以正常工作、立即崩溃、稍后崩溃或导致恶魔飞出您的鼻子。如果你的程序有未定义的行为,你就无法推理它,因为你不知道它会做什么。所以是的,这可能是你的问题。

标签: c++ class vector stl


【解决方案1】:

我修好了。我重建了解决方案并在删除后将所有指针设置为 NULL。这修复了发生在堆上的所有损坏。感谢那些帮助过的人。

故事的寓意: 始终在损坏您的构建之前修复堆错误的损坏!

【讨论】:

    猜你喜欢
    • 2022-06-12
    • 1970-01-01
    • 2011-04-19
    • 1970-01-01
    • 2020-09-04
    • 2018-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多