2012-03-19 29 views
10

Tôi cố gắng để biên dịch một chương trình biên dịch hoàn toàn tốt đẹp trên desktop của tôi, nhưng trên máy tính xách tay của tôi, nó biên dịch nhưng mang lại cho tôi lỗi này bất cứ khi nào nó được điều hành:Heap tham nhũng nhưng chỉ khi biên soạn trên máy tính xách tay

Windows có kích hoạt một điểm ngắt trong RR.exe.

Điều này có thể do hỏng heap, cho biết lỗi trong RR.exe hoặc bất kỳ tệp DLL nào đã tải.

Điều này cũng có thể do người dùng nhấn F12 trong khi RR.exe đã tập trung.

Cửa sổ đầu ra có thể có thêm thông tin chẩn đoán.

tôi đã nhận xét ra dòng cho đến khi tôi tìm thấy dòng mà làm cho các lỗi đó là:

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

Điều lạ là nếu tôi thay width_height_ với các hằng số, ví dụ 800 và 600 tương ứng, nó dừng tham nhũng đống. Ngoài ra nếu tôi chỉ sử dụng các giá trị mặc định được thiết lập bởi hàm tạo thay vì truyền các giá trị, nó sẽ không sụp đổ.

Đây là mã hoàn chỉnh. Các dòng trên nằm trong hàm tạo 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; 
} 
+3

1 để cung cấp một, kiểm tra hợp cụ thể tương đối ngắn hoàn chỉnh. –

+1

bạn đã đảm bảo bạn có chính xác cùng một phiên bản của hệ thống/thời gian chạy DLL trên cả hai máy? –

+0

Chúng là chính xác cùng một DLL, .libs và pro ject như tôi giữ chúng trên dropbox. – Lerp

Trả lời

6

vấn đề này dường như dẫn đầu với glfw:

tôi giả sử, bạn đang cố gắng sử dụng liên kết động GLFW. Lưu ý trong phần đầu 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 dường như đã được thiết lập trong khi xây dựng dll, và nó được xác định chức năng API với __stdcall gọi hoán cải.

Nhưng khi sử dụng thư viện bạn chưa xác định GLFW_DLL, vì vậy mã của bạn giả định __cdecl chuyển đổi cuộc gọi.Sự khác biệt giữa _cdecl__stdcall nói chung là chức năng người gọi nên làm sạch ngăn xếp trước tiên và callee trong trường hợp cuối cùng. Vì vậy, bạn làm sạch ngăn xếp hai lần, đó là lý do tại sao bạn có stack tham nhũng.

Sau khi tôi đã xác định GLFW_DLL trước khi bao gồm glfw trong chương trình của bạn, nó bắt đầu hoạt động chính xác. Cũng lưu ý rằng tôi đã sử dụng mingw và phải liên kết với glfwdll.a thay vì glfw.a sau khi xác định GLFW_DLL.

+0

Điều này cũng làm việc cho tôi. Tôi quản lý để cũng làm cho nó hoạt động bằng cách thay đổi thư viện Runtime cho DLL đa luồng Debug thành DLL đa luồng. Bạn có thể giải thích lý do tại sao truyền các giá trị không đổi thay vì các biến không gây ra lỗi tham nhũng? Liệu nó gọi hàm có vẻ khác nhau khi tất cả các đối số đều không đổi? – Lerp

+0

@Rarge, "Thư viện thời gian chạy cho DLL đa luồng Debugging cho DLL đa luồng" dường như được kết nối với một số công cụ WinCRT, chứ không phải GLFW. Không đặt giá trị không đổi hoặc thay đổi cài đặt dự án _prevents_ heap tham nhũng, nhưng chỉ _hides_ nó. – Lol4t0

1

Heap tham nhũng lỗi almomst không bao giờ biểu hiện tại thời điểm ban đầu chúng xảy ra, đó là những gì làm cho chúng rất đau đớn để chẩn đoán. Thực tế là nó hoạt động trên một hệ thống và không phải là một hệ thống khác ngụ ý hành vi không xác định.

Tôi không thấy bất kỳ lỗi rõ ràng nào trong việc kiểm tra nhanh mã của bạn. Nếu bạn có quyền truy cập vào Purify cho Windows, hoặc thay thế khả năng biên dịch trên Linux, bạn có thể sử dụng valgrind. Một trong những công cụ này sẽ có sự thay đổi thành công cao hơn nhiều so với kiểm tra mã đơn giản mà tôi tin.

0

Một giải pháp khác tôi đi qua:

Bằng cách thay đổi Runtime Library (Project Properties> C/C++> từ Multi-ren gỡ lỗi DLL (/ MDD) để DLL Multi-ren (/ MD) tham nhũng đống không còn xảy ra.

tôi không biết lý do tại sao mặc dù, có lẽ ai đó có kiến ​​thức nhiều hơn có thể có thể làm sáng tỏ về vấn đề này.

Các vấn đề liên quan