Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

16.02.2012, 23:50

Heap beschädigung bei Dekonstruktor Aufruf

Guten Abend ich bin mittlerweile im 4 Anlauf mir mal ernsthaft C++ anzueignen und diesmal denke ich das ich genug motivation habe es auch zu schaffen. Zu meinem Problem, ich habe ein eKlasse "dxRenderWindow" in einer externen Dll und möchte die Klasse in meinem Spiel verweden. Soweit funktioniert das ganze auch nur wenn mein Programm dann geschlossen wird bzw. per delete der dtor von "dxRenderWindow" aufgerufen wird bekomme ich einen Fehler das der Stack um meine "dxRenderWindow"-Variable corrumpiert ist.

Da der Debugger manchmal bei UnregisterClassEx() hängen bleibt glaube ich das es etwas damit zu tun hat, komisch ist nur das ich den Fehler trozdem erhalte auch wenn der dtor komplett leer ist (Ja ich hab die Dll vorher neuerstellen lassen).

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// dxRenderWindow.hpp
class __declspec(dllExport) dxRenderWindow
{
public:
    dxRenderWindow(void);
    ~dxRenderWindow(void);
    /*...unwichtige Member entfernt...*/
private:
    /*...unwichtige Member entfernt...*/
    dxRenderWindowParamter *m_dxWindowParameter;
    static BOOL m_classRegistered;
    static WNDCLASSEX m_dxRenderClass;
};

// dxRenderWindow.cpp
#include "dxRenderwindow.hpp"

dxRenderWindow::dxRenderWindow(void)
    : m_hWnd (NULL), m_dxWindowParameter( NULL )
{
    if (dxRenderWindow::m_classRegistered != TRUE)
    {
        ZeroMemory( &dxRenderWindow::m_dxRenderClass, sizeof(WNDCLASSEX));

        dxRenderWindow::m_dxRenderClass.cbSize = sizeof(WNDCLASSEX);
        dxRenderWindow::m_dxRenderClass.hInstance = GetModuleHandle( NULL );
        dxRenderWindow::m_dxRenderClass.lpszClassName = L"dxRenderWindowClass";
        dxRenderWindow::m_dxRenderClass.style = CS_HREDRAW | CS_VREDRAW;
        dxRenderWindow::m_dxRenderClass.lpfnWndProc = (WNDPROC)staticDefWndProc;

        RegisterClassEx( &dxRenderWindow::m_dxRenderClass );
        dxRenderWindow::m_classRegistered = TRUE;
    }
}
dxRenderWindow::~dxRenderWindow(void)
{
    
    if (m_dxWindowParameter != NULL)
    {
        delete m_dxWindowParameter;
    }
    if (dxRenderWindow::m_classRegistered)
    {
// Hier bleibt der Debugger manchmal hängen
// aber selbst wenn ich den ganzen dtor leer habe kommt es zu dem Fehler
        UnregisterClass( L"dxRenderWindowClass", GetModuleHandle( NULL ) ); 
    }
}

// main.cpp vom aufrufer Programm
int main()
{
    dxRenderWindow *window = new dxRenderWindow();
    std::cout << "Test vor delete"; // das wird noch angezeigt
    delete window;
    std::cout << "Test nach delete"; // das nichtmehr
    return 0;
}
greate minds discuss ideas;
average minds discuss events;
small minds discuss people.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Sortoc« (17.02.2012, 00:18)


drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

2

16.02.2012, 23:58

Wenn du m_dxWindowParameter nicht initialisierst ist es != NULL. Und da du im gezeigten Code nirgends etwas zuweist führt das delete zu undefiniertem Verhalten, was manchmal durch einen Fehler bemerkbar ist.

3

17.02.2012, 00:18

Nein daran sollte es nicht liegen ich habe den Konstruktor eigentlich so im Code stehen:

C-/C++-Quelltext

1
2
3
dxRenderWindow::dxRenderWindow(void)
    : m_hWnd (NULL), m_dxWindowParameter( NULL )
{...}


Ich dachte nur das wäre unwichtig für die Fehlersuche, ich werde es mal im Startposting korriegieren.
greate minds discuss ideas;
average minds discuss events;
small minds discuss people.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

4

17.02.2012, 00:28

Du bekommst wirklich den Fehler dass der Stack korrupt ist? In dem Fall hats wohl nix mit dem Objekt am Heap zu tun ;)

5

17.02.2012, 00:55

Ahh ich habe die Fehlrmeldungen von 2 unterschiedlichen Versuchen durcheinader geworfen.
Ok jetzt nochmal Code mit Fehlermeldung:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
int main()
{
    dxRenderWindow *window = new dxRenderWindow();
    std::cout << "Test vor delete"; // das wird noch angezeigt
    delete window;
    std::cout << "Test nach delete"; // das nichtmehr
    return 0;
}

Produziert diesen Fehler:

(Link)


C-/C++-Quelltext

1
2
3
4
5
int main()
{
dxRenderWindow window;
return 0;
}

Dieser Fehler:

(Link)
greate minds discuss ideas;
average minds discuss events;
small minds discuss people.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

6

17.02.2012, 09:49

Ok, damit isses relativ klar. Irgendwo wird wohl auf Speicher geschrieben der nichtmehr zum dxRenderWindow Objekt gehört. Sind unter den "unwichtigen" Membern vielleicht irgendwelche Arrays, Vektoren, Strings etc.?

7

17.02.2012, 13:05

Ich kopiere einfach mal die komplette Header/Cpp Datei.

dxRenderWindow.hpp

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#ifndef dxRenderWindow_h__
#define dxRenderWindow_h__

#include "dxRender.hpp" // Hier wird DLLTOKEN definiert
#include "dxWindowStruct.hpp" // Includiert "dxRenderWindowParameter.hpp"

class DLLTOKEN dxRenderWindow // DLLTOKEN ist in dem Dll-Projekt __declspec(dllexport) ansonsten __declspec(dllImport)
{
public:
    dxRenderWindow(void);
    ~dxRenderWindow(void);

    BOOL create( const dxRenderWindowParamter *dxWindowParameter );
private:
    HWND m_hWnd;
    dxRenderWindowParamter *m_dxWindowParameter;

    // Static stuff
    static LRESULT staticDefWndProc( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );
    static BOOL m_classRegistered;
    static WNDCLASSEX m_dxRenderClass;
};

#endif // dxRenderWindow_h__


dxRenderWindow.cpp

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include "dxRenderWindow.hpp"

// Static Init
BOOL dxRenderWindow::m_classRegistered = FALSE;
WNDCLASSEX dxRenderWindow::m_dxRenderClass = WNDCLASSEX();
// End Static Init

dxRenderWindow::dxRenderWindow(void)
    : m_hWnd (NULL), m_dxWindowParameter( NULL )
{
    if (dxRenderWindow::m_classRegistered != TRUE)
    {
        ZeroMemory( &dxRenderWindow::m_dxRenderClass, sizeof(WNDCLASSEX));

        dxRenderWindow::m_dxRenderClass.cbSize = sizeof(WNDCLASSEX);
        dxRenderWindow::m_dxRenderClass.hInstance = GetModuleHandle( NULL );
        dxRenderWindow::m_dxRenderClass.lpszClassName = L"dxRenderWindowClass";
        dxRenderWindow::m_dxRenderClass.style = CS_HREDRAW | CS_VREDRAW;
        dxRenderWindow::m_dxRenderClass.lpfnWndProc = (WNDPROC)staticDefWndProc;

        RegisterClassEx( &dxRenderWindow::m_dxRenderClass );
        dxRenderWindow::m_classRegistered = TRUE;
    }
}
dxRenderWindow::~dxRenderWindow(void)
{
    
    if (m_dxWindowParameter != NULL)
    {
        delete m_dxWindowParameter;
    }
    if (dxRenderWindow::m_classRegistered)
    {
        UnregisterClass( L"dxRenderWindowClass", GetModuleHandle( NULL ) );
    }
}
BOOL dxRenderWindow::create( const dxRenderWindowParamter *dxWindowParameter )
{
    m_dxWindowParameter = new dxRenderWindowParamter();
    *m_dxWindowParameter = *dxWindowParameter;

    m_hWnd = CreateWindowEx(    WS_CAPTION | WS_BORDER,
                    dxRenderWindow::m_dxRenderClass.lpszClassName,
                    m_dxWindowParameter->lpszCaption,
                    dxRenderWindow::m_dxRenderClass.style,
                    0,
                    0,
                    m_dxWindowParameter->iWidth,
                    m_dxWindowParameter->iHeigth,
                    NULL,
                    NULL,
                    dxRenderWindow::m_dxRenderClass.hInstance,
                    NULL);

    if (m_hWnd != NULL)
    {
        SetWindowLong( m_hWnd, GWL_USERDATA, (LONG)this );
        std::cout << "created::dxRenderWindow at " << &m_hWnd << " (" << m_hWnd << ")\n";
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}
LRESULT dxRenderWindow::staticDefWndProc( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam )
{
    dxRenderWindow *pRenderWindow = ( dxRenderWindow* ) GetWindowLong( hWnd, GWL_USERDATA );
    return pRenderWindow->m_dxWindowParameter->lpfnWndProc( hWnd, Msg, wParam, lParam);
}


dxRenderWindowParameter.hpp

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef dxWindowStruct_h__
#define dxWindowStruct_h__

#include "dxRender.hpp"

struct DLLTOKEN dxRenderWindowParamter 
{
    int iWidth;
    int iHeigth;
    LPCWSTR lpszCaption;
    WNDPROC lpfnWndProc;
};

#endif // dxWindowStruct_h__
greate minds discuss ideas;
average minds discuss events;
small minds discuss people.

8

18.02.2012, 12:50

Ok es scheint an dem Member m_hWnd zu liegen wenn ich den auskommentiee bekomme ich keine Fehlermeldung mehr. Kann es sein das da irgendwo in der windows.h was nicht richtig funktioniert?
greate minds discuss ideas;
average minds discuss events;
small minds discuss people.

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

9

18.02.2012, 13:06

Nein. Eher nicht. Dass die Fehlermeldung manchmal kommt und wieder geht wenn du gewisse Stellen auskommentierst hat nicht unbedingt etwas mit dem tatsächlichen Grund zu tun. Das kann daran liegen, dass dadurch halt zufälligerweise der Fehler nicht erzeugt wird aus welchen Gründen auch immer (weil dann z.B nichts "böses" gemacht wird).

Was du auf jeden Fall genauer anschauen musst ist diese komische statische Abhängigkeit mit den Klassen Objekten. Wenn da nämlich mehrere Objekte bestehen, dann kann das arg in die Hose gehen. Vielleicht hat es damit etwas zu tun.

10

18.02.2012, 13:44

Ich habe mir gedacht bevor jedesmal wenn ein neues dxRenderWindow erstellt wird eine neue WNDCLASS registriert wird mach ich das mit einer statischen Variable. Gib es denn eine möglichkeit bazufragen ob eine WNDCLASS mit Namen XY schon registriert wurde?
greate minds discuss ideas;
average minds discuss events;
small minds discuss people.

Werbeanzeige