堆腐败,但只有在笔记本电脑上编译

Ler*_*erp 10 c++ glfw

我正在尝试编译一个程序,在我的桌面上编译完全正常,但在我的笔记本电脑上,它编译,但每次运行时都会给我这个错误:

Windows已在RR.exe中触发了断点.

这可能是由于堆损坏,这表明RR.exe或其加载的任何DLL中存在错误.

这也可能是由于用户在RR.exe具有焦点时按下F12.

输出窗口可能包含更多诊断信息.

我已经注释掉了行,直到找到导致错误的行:

if(glfwOpenWindow(width_, height_, 0, 0, 0, 0, 32, 0, GLFW_WINDOW) != GL_TRUE) {
    throw std::runtime_error("Unable to open GLFW window");
}
Run Code Online (Sandbox Code Playgroud)

奇怪的是,如果我替换width_height_常量,例如分别为800和600,它会停止堆损坏.此外,如果我只使用构造函数设置的默认值而不是传递值,它不会崩溃.

这是完整的代码.上面的行在Window构造函数中.

在window.h

#pragma once

#include <iostream>
#include <GL\glew.h>
#include <GL\glfw.h>

#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")
#pragma comment(lib, "glew32.lib")
#pragma comment(lib, "GLFW.lib")

class Window {
public:
    Window(unsigned width = 800, unsigned height = 600);
    ~Window();

    void clear();
    inline void display() { glfwSwapBuffers(); }
    inline bool exit() { return !glfwGetWindowParam(GLFW_OPENED); }

private:
    unsigned width_, height_;
};
Run Code Online (Sandbox Code Playgroud)

window.cpp

#include "window.h"

Window::Window(unsigned width, unsigned height) : width_(width), height_(height) {
    if(glfwInit() != GL_TRUE) {
        throw std::runtime_error("Unable to initialize GLFW");
    }

    if(glfwOpenWindow(width_, height_, 0, 0, 0, 0, 32, 0, GLFW_WINDOW) != GL_TRUE) { //crash
    //if(glfwOpenWindow(800, 600, 0, 0, 0, 0, 32, 0, GLFW_WINDOW) != GL_TRUE) { //no crash
        throw std::runtime_error("Unable to open GLFW window");
    }

    GLenum result = glewInit();
    if(result != GLEW_OK) {
        std::stringstream ss;
        ss << "Unable to initialize glew: " << glewGetErrorString(result);
        throw std::runtime_error(ss.str());
    }
}

Window::~Window() {
    glfwTerminate();
}

void Window::clear() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
}
Run Code Online (Sandbox Code Playgroud)

main.cpp中

#include "window.h"

int main() {
    Window wind(1024, 800); //crash
    Window wind(800, 600); //crash
    Window wind(); //works

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Lol*_*4t0 6

这个问题似乎与glfw有关:

我假设,您正在尝试使用动态链接GLFW.请注意glfw标头:

#if defined(_WIN32) && defined(GLFW_BUILD_DLL)

/* We are building a Win32 DLL */
 #define GLFWAPI      __declspec(dllexport)
 #define GLFWAPIENTRY __stdcall
 #define GLFWCALL     __stdcall
#elif defined(_WIN32) && defined(GLFW_DLL)

 /* We are calling a Win32 DLL */
 #if defined(__LCC__)
  #define GLFWAPI      extern
 #else
  #define GLFWAPI      __declspec(dllimport)
 #endif
 #define GLFWAPIENTRY __stdcall
 #define GLFWCALL     __stdcall

#else

 /* We are either building/calling a static lib or we are non-win32 */
 #define GLFWAPIENTRY
 #define GLFWAPI
 #define GLFWCALL

#endif
Run Code Online (Sandbox Code Playgroud)

GLFW_BUILD_DLL显然是在构建dll时设置的,它通过__stdcall调用转换定义了API函数.

但是当你使用库时你没有定义GLFW_DLL,所以你的代码假设__cdecl调用转换._cdecl和之间的区别__stdcall通常是调用函数应该首先清理堆栈,在最后一种情况下调用callee.所以你清理了两次堆栈,这就是堆栈损坏的原因.

在我在您的程序中GLFW_DLL包含之前定义之后glfw,它开始正常工作.另请注意,我使用了mingw并且必须链接glfwdll.a而不是glfw.a在定义之后GLFW_DLL.