我正在尝试编译一个在我的桌面上完全编译的程序,但是在我的笔记本电脑上,它会编译,但只要它运行就会给我这个错误:
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");
}
奇怪的是,如果我用常量替换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_;
};
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();
}
的main.cpp
#include "window.h"
int main() {
Window wind(1024, 800); //crash
Window wind(800, 600); //crash
Window wind(); //works
return 0;
}
答案 0 :(得分: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
显然在构建dll时设置了 GLFW_BUILD_DLL
,并且它使用__stdcall
调用转换定义了API函数。
但是在使用库时,您尚未定义GLFW_DLL
,因此您的代码假定__cdecl
调用转换。 _cdecl
和__stdcall
之间的区别通常是调用函数应首先清除堆栈,最后清除 callee 。所以你清理了两次堆栈,这就是堆栈损坏的原因。
在我将[{1}}包含在您的程序之前定义GLFW_DLL
后,它开始正常运行。另请注意,我使用mingw并且在定义glfw
后必须与glfwdll.a
而不是glfw.a
相关联。
答案 1 :(得分:1)
堆腐败漏洞似乎永远不会在它们最初发生时出现,这就是使它们诊断如此痛苦的原因。它在一个系统而不是另一个系统上工作的事实意味着未定义的行为。
在快速检查代码时,我没有看到任何明显的错误。如果您可以访问Purify for Windows,或者在Linux上替代编译功能,则可以使用valgrind。与我认为的简单代码检查相比,这些工具中的任何一个都会有更高的成功率。
答案 2 :(得分:0)
我遇到的另一种解决方案:
通过将运行时库(项目属性&gt; C / C ++&gt;从多线程调试DLL(/ MDd))更改为多线程DLL(/ MD),不再发生堆损坏。
我不知道为什么,也许有更多知识的人可以对此有所了解。