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

Dofter

Treue Seele

  • »Dofter« ist der Autor dieses Themas

Beiträge: 159

Wohnort: im wunderbaren EBERMANNSTADT

Beruf: Schüler^^

  • Private Nachricht senden

1

28.10.2007, 14:10

Invalid Address specified to RtlValidateHeap

Hi!

Ich hab mal wieder ien kleines Problemchen.
Für mien Projekt benutze ich tbGUI, also die benutzeroberfläche der TRIBase engine, doch ich hab mehr Elemente gebraucht wie z.B. einen Knopf mit einem Bild. Also hab ich mir gedacht, erweitern wir sie einfach, doch da diese Knöpfe Spielspezifisch sind wollte ich sie nicht in die Engine mit einbaun, also hab ich mir gedahct, ich mach ne erweiterte GUI-Klasse, die ich von tbGUI ableite. und in diese Klasse schreib ich dann die neuen Erzeugungsmethoden. Die neuen Elemente leidte ich wie die "normalen" auch von tbGUIElement ab.
Das erzeugen, das hinzufügen und das zeichnen klicken,... Klappt alles, bloß nicht das löschen, Wenn ich eines meiner neuen Elemente löschen will kommt dieser fehler bei TB_SAFE_DELETE(pElement):

Zitat

HEAP[Projekt Schneehase.exe]: Invalid Address specified to RtlValidateHeap( 00D80000, 00DAC178 )
Windows hat einen Haltepunkt in Projekt Schneehase.exe ausgelöst.

Dies kann auf eine Beschädigung des Heaps zurückzuführen sein und weist auf ein Problem in Projekt Schneehase.exe oder in einer der geladenen DLLs hin.

Weitere Analyseinformationen finden Sie möglicherweise im Ausgabefenster.


ich habe keine ahnung was ich damit anfangen soll. Hier noch etwas Code:


Hier die Erzeugungsmethode:

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
// erstellt einen Knopf mit irgendeinem Bild

tbResult CExtendedGUI::CreatePictureButton(int iID,
                          int iPage,
                          tbVector2 vPosition,
                          tbVector2 vSize,
                          tbVector2 vTextLU,
                          tbVector2 vTextRD,
                          int iEffect)
{
    tbGUIElement*   pElement;
    CPictureButton*     pButton;


    // Knopf erstellen

    pElement = new CPictureButton;

    // Daten eintragen

    pElement->SetID(iID);
    pElement->SetType(GET_GUIBUTTON);
    pElement->SetPage(iPage);
    pElement->SetGUI(this);
    pElement->SetPosition(vPosition);
    pElement->SetSize(vSize);
    pElement->Show(TRUE);
    pElement->Enable(TRUE);
    pElement->SetEffect(iEffect);
    

    // Liste erweitern

    pElement = AddElement(pElement);

    // Erstellungsnachricht verschicken

    tbGUIMessage Msg;
    ZeroMemory(&Msg, sizeof(tbGUIMessage));
    Msg.Type = TB_GMT_CREATE;
    PostMessage(iID, &Msg);

    // Daten eintragen

    pButton = (CPictureButton*)(pElement);

    // Texturkoordinaten setzen

    pButton->GetVertices()[V_LEFTDOWN].vTexture     = tbVector2(vTextLU.x,vTextRD.y);
    pButton->GetVertices()[V_LEFTUP].vTexture       = vTextLU;
    pButton->GetVertices()[V_RIGHTDOWN].vTexture    = vTextRD;
    pButton->GetVertices()[V_RIGHTUP].vTexture      = tbVector2(vTextRD.x,vTextLU.y);

    return TB_OK;
}

Und hier der löschvorgang:
// Löscht ein Element

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
tbResult tbGUI::DeleteElement(int iID)
{
    // Element suchen

    tbListEntry<tbGUIElement*>* pEntry = GetElementListEntry(iID);
    if(!pEntry) TB_ERROR("Das Element wurde nicht gefunden!", TB_ERROR);
    tbGUIElement* pElement = pEntry->Data;

    // Löschungsnachricht schicken

    tbGUIMessage Msg;
    ZeroMemory(&Msg, sizeof(tbGUIMessage));
    Msg.Type = TB_GMT_DELETE;
    PostMessage(iID, &Msg);

    // Das Element löschen

    TB_SAFE_DELETE(pElement);           <== hier kommt dieser Fehler
    m_pElements->DeleteEntry(pEntry);

    return TB_OK;
}


ich hoffe das irgendjemand ne ahnung hat.

mfg Dofter
"Wo kämen wir hin, wenn alle sagten, wo kämen wir hin, und keiner ginge,
um zu sehen, wohin wir kämen, wenn wir gingen"

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

2

28.10.2007, 21:56

Hi, setz mal einen Haltepunkt genau auf des löschen und schau, was für Werte dein Zeiger hat. Der hat miit 99,9% Wahrscheinlichkeit totalen Stuss da stehen, denn du schickst vorher eine Nachricht an das System, was ja das Löschen des GUIElements einleitet. Wenn nun dabei der Speicher schon freigeben wird, versuchst du mit deinem TB_SAFE_DELETE(pElement); ein schon gelöschten Bereich nochmal zu löschen.
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

Dofter

Treue Seele

  • »Dofter« ist der Autor dieses Themas

Beiträge: 159

Wohnort: im wunderbaren EBERMANNSTADT

Beruf: Schüler^^

  • Private Nachricht senden

3

29.10.2007, 10:48

sry. hab ich schon nachgeschaut. der Zeiger weist auf einen gültigen Speicherbereich, und ist in TB_SAFE_DELETE auch noch gültig.
zum glück hast du nur 99,9% geschrieben ;)

Die nachricht wird nicht an das system geschickt, sondern an das Element, dass diese für sich reservierten Speicherbereich wieder freigibt.
"Wo kämen wir hin, wenn alle sagten, wo kämen wir hin, und keiner ginge,
um zu sehen, wohin wir kämen, wenn wir gingen"

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

4

29.10.2007, 17:07

Was passiert wenn du die Nachricht nicht schickst? Schonmal Probiert? Ansonsten müsstest du mal nach ungültigen Zeigeraddressen schauen. Also ob irgendein Zeiger in einen anderen gecastet wird, obwohl die Typen eigentlich nicht kompatibel sind oder man über ein Buffer hinausschreibt.
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

Dofter

Treue Seele

  • »Dofter« ist der Autor dieses Themas

Beiträge: 159

Wohnort: im wunderbaren EBERMANNSTADT

Beruf: Schüler^^

  • Private Nachricht senden

5

29.10.2007, 18:04

die nachrichtenschickmethode schaut so aus:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Senden einer Nachricht

tbResult tbGUI::PostMessage(int iID,
                            tbGUIMessage* pMsg)
{
    tbGUIElement*   pElement;
    tbResult        (* pMsgProc)(int, tbGUIMessage*, tbGUI*);


    // Die Nachrichtenfunktion des Elements aufrufen

    pElement = GetElement(iID);
    if(!pElement) TB_ERROR("Das Element wurde nicht gefunden!", TB_ERROR);
    pElement->ReceiveMessage(pMsg);

    // Die allgemeine Nachrichtenfunktion aufrufen

    pMsgProc = (tbResult (*)(int, tbGUIMessage*, tbGUI*))(m_pMsgProc);
    pMsgProc(iID, pMsg, this);

    return TB_OK;
}


Diese ReceiveMessage-Methode eines Elementes sieht so aus:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
tbResult CGUIButton::ReceiveMessage(const tbGUIMessage* pMsg)
{
    tbColor Color;

    switch (pMsg->Type)
    {
    case TB_GMT_CREATE:
        // hier ist unrelevanter Code

        break;
    case TB_GMT_MOVE:
        // hier ist unrelevanter Code

        break;
    case TB_GMT_RENDER:
        // hier ist unrelevanter Code

        break;
    }
    return TB_OK;
}

und die allgemeine, also die der GUI schaut auch nicht viel anders aus:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
tbResult CGUI::GUIMenuMsgProc(int iID,
                         tbGUIMessage* pMsg,
                         tbGUI* pGUI)
{
    switch(pMsg->Type)
    {
    case TB_GMT_ELEMENTCLICKED:
        switch(iID)
        {
        case ID_NEXT:
            FindParent(this,"CGame")->NextMove();
            break;
        }
        break;
    }
    return TB_OK;
}

wie meinst du des mit ungültigen zeigeradressen? also pEntry, pEntry->Data sowie pElement weisen soweit ich des beobachten kann auf eine gültige, und die richtige Adresse( damit meine ich: die Adresse die der Knopf beim Erstellen hat hat er auch bei delete). alle Variablen(von allen Klassen von denen ese diese haben sollte) haben korrekte Werte.

Und wei meinst du des mit dem falschzen casten, bzw. übern Buffer hinausschreiben?

(Wenn ich dir ein bild von den Werten der Variablen bei Debuggen schicken soll, mach ich des)

Vielen Dank schonmal
Dofter
"Wo kämen wir hin, wenn alle sagten, wo kämen wir hin, und keiner ginge,
um zu sehen, wohin wir kämen, wenn wir gingen"

Werbeanzeige