Куча Коррупция, но только при компиляции на ноутбуке
Я пытаюсь скомпилировать программу, которая отлично компилируется на моем рабочем столе, но на моем ноутбуке она компилируется, но дает мне эту ошибку всякий раз, когда она запускается:
Windows вызвала точку останова в файле RR.exe.
Это может быть связано с повреждением кучи, что указывает на ошибку в RR.exe или любой из загруженных DLL файлов.
Это также может быть вызвано нажатием кнопки F12, когда RR.exe имеет фокус.
В окне вывода может быть больше диагностической информации.
Я прокомментировал строки, пока не нашел строку, которая делает ошибку, которая:
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;
}
Ответы
Ответ 1
Кажется, что проблема связана с 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
GLFW_BUILD_DLL
, по-видимому, был установлен при построении dll, и он определил функции API с преобразованием вызова __stdcall
.
Но при использовании библиотеки вы не определили GLFW_DLL
, поэтому ваш код предположил, что __cdecl
вызывает преобразование. Разница между _cdecl
и __stdcall
в общем случае заключается в том, что функция вызывающего абонента должна очистить стек в первом и вызываемом в последнем случае. Таким образом, вы дважды очистили стек, поэтому у вас возникло повреждение стека.
После того, как я определил GLFW_DLL
, прежде чем включать GLFW
в вашу программу, он начал работать правильно. Также обратите внимание, что я использовал mingw и должен был связываться с glfwdll.a
вместо glfw.a
после определения GLFW_DLL
.
Ответ 2
Ошибки ошибок кучи almomst никогда не проявляются в той точке, в которой они изначально происходят, что и делает их настолько болезненными для диагностики. Тот факт, что он работает на одной системе, а не другой, подразумевает поведение undefined.
Я не видел никаких явных ошибок при быстрой проверке вашего кода. Если у вас есть доступ к очистке для Windows или альтернатива компиляции на Linux, вы можете использовать valgrind. Любой из этих инструментов будет иметь гораздо более высокое изменение успеха, чем простая проверка кода, которую я считаю.
Ответ 3
Другое решение, с которым я столкнулся:
Изменив библиотеку времени выполнения (свойства проектa > C/С++ > из многопоточной DLL (/MDd) для многопоточной DLL (/MD), повреждение кучи больше не произошло.
Я не знаю, почему, хотя, возможно, кто-то с большим количеством знаний может пролить свет на это.