【问题标题】:vector, sfml and "the value of esp was not properly saved across the function call" error矢量、sfml 和“esp 的值未在函数调用中正确保存”错误
【发布时间】:2015-09-06 22:49:38
【问题描述】:

我有一个结构“Layer”和类“LayerHandler”。图层只包含一个纹理、精灵和两个构造函数——一个是默认的,一个是带有参考参数的。 LayerHandler 类是一个处理我们拥有的所有图层的绘制的类。我将图层添加到这个类,然后我使用 win.draw(layerhandler_object) 来绘制所有内容。 LayerHandler 继承自 Drawable 以执行此操作,它覆盖了 virtual void draw()。

LayerHandler.h:

#ifndef LAYERHANDLER_H
#define LAYERHANDLER_H

#include <vector>
#include <SFML\Graphics.hpp>

using namespace std;
using namespace sf;

struct Layer {
    Texture tex;
    Sprite spr;

    Layer() { }

    Layer(Layer& l) {
        tex = l.tex;
        spr = l.spr;
    }
};

class LayerHandler : public Drawable {
    private:
        vector<Layer*> layers;

        virtual void draw(RenderTarget& target, RenderStates states) const {
            for (int i=0; i<layers.size(); i++)
                target.draw(layers[i]->spr, states);
        }

    public:
        LayerHandler();
        ~LayerHandler();
        void Add(Layer& layer);
};

#endif

LayerHandler.cpp:

#include "LayerHandler.h"

LayerHandler::LayerHandler() {

}

LayerHandler::~LayerHandler() {

}

void LayerHandler::Add(Layer& layer) { 
    layers.push_back(new Layer(layer)); 
}

和 main.cpp:

#include <iostream>
#include <SFML\Graphics.hpp>
#include "LayerHandler.h"

using namespace std;
using namespace sf;

int main() {
    RenderWindow win(VideoMode(800, 600), "Raven", Style::Default);
    win.setFramerateLimit(60);
    win.setVerticalSyncEnabled(true);
    win.setMouseCursorVisible(false);

    LayerHandler lhandler;

    Layer back;
    back.tex.loadFromFile("bao/gfx/back.png");
    back.spr.setTexture(back.tex);
    back.spr.setPosition(0, 50);

    lhandler.Add(back);

    Event evt;

    float dt = 0.f;
    Clock clock;
    float dwticks = clock.getElapsedTime().asMilliseconds();
    float dwnewticks = 0.f;

    while (win.isOpen()) {
        if (win.pollEvent(evt)) {
            if (Keyboard::isKeyPressed(Keyboard::Key::Escape)) {
                win.close();
            }
        } else {
            dwnewticks = clock.getElapsedTime().asMilliseconds();
            dt = dwnewticks > dwticks ? (dwnewticks - dwticks) / 4000.f : 0.f;
            dwticks = dwnewticks;

            win.clear();
            win.draw(lhandler);
            win.display();
        }
    }

    return 0;
}

我认为这并不复杂,而且我做的一切都很好,但我得到这个“ESP 的值没有在函数调用中正确保存”错误。我不知道为什么会收到此错误。我知道这可能是由不匹配的调用约定引起的,但我在我的代码中没有看到类似的东西......我不得不说这是我第一次遇到这个错误,我完全出局了想法如何处理它。有什么帮助吗?

【问题讨论】:

  • 一些可能不是您的麻烦的原因,但仍然需要了解的重要事项:don't use both setFramerateLimit and setVerticalSyncEnabled 和您的图层复制 ctor 应该 a) 将 const ref 作为参数,b) 设置sprtex 的纹理,而不是保留 l.tex。您还应该避免在头文件中使用 using 语句并使用 / 而不是非标准的 `` 路径。最后,使用智能指针或至少释放你的内存。
  • 我删除了 setFramerateLimit,只留下了 setVerticalSyncEnabled。我还将spr = l.spr 更改为spr.setTexture(tex),但我不同意我的复制ctor 应该将const ref 作为参数,因为引用已经是一个常量指针。感谢您的帮助,我将尝试释放内存并阅读有关智能指针的信息。希望它会有所帮助。
  • 但我得到这个“ESP 的值没有在函数调用中正确保存”错误。我不知道为什么会出现此错误。 堆栈损坏。
  • 是的,我知道这是堆栈损坏,但我不知道如何修复它。也许我应该使用 _stdcall?
  • 我不认为调用约定与问题有任何关系。虽然我看不到您超出任何堆栈变量的范围。

标签: c++ vector stack sfml stack-pointer


【解决方案1】:

不知道为什么,但问题出在 SFML 库上。在这里,我将 2.2 版用于 32 位应用程序。我下载了 2.3 32 位版本并使用新的 2.3 库编译了我的应用程序,现在它可以完美运行了。

【讨论】:

  • 对于出现此问题的库,您使用的是为您的编译器版本还是其他 Visual Studio 版本构建的库?尽管有 crt 冲突,但我预计堆损坏比堆栈损坏的可能性更大。
  • 我确定我在 Visual Studio 版本 (2010) 中使用了库。我从来没有安装过任何其他版本的 Visual c++,所以我确信我不会下载 Visual 2013 的库,例如。更重要的是,我使用 2.2 库编写了一个 arkanoid/breakout 克隆,它运行良好,尽管当我尝试覆盖可绘制类时,我再次遇到了 esp 错误。但后来我只是写了一个返回对象精灵的方法,所以我可以这样画:window.draw(myobject.getSprite());.
猜你喜欢
  • 2013-07-03
  • 1970-01-01
  • 2012-04-06
  • 2012-01-30
  • 2013-11-30
  • 2011-09-17
  • 1970-01-01
  • 1970-01-01
  • 2010-09-13
相关资源
最近更新 更多