Toon posts:

[C++]Debug error: damage after normal block

Pagina: 1
Acties:

Verwijderd

Topicstarter
Heb weer iets vaags, heb dit nog nooit gehad:
Ik gebruik in een programma om het koninginnenprobleem op te lossen een dubbele vector die het schaakbord voorsteld met daarin objecten van het type "vak". En vak heb ik d.m.v. een struct gedefinieerd en stellen gewoon twee booleans voor (een boolean om te zien of er een koningin opstaat en een boolean om te zien of dat vakje al eens gecontroleerd is) ('t is via backtracking).
Kortom gewoon wat standaard simple stuff dacht ik. Ik laat het programma runnen en ik krijg een oplossing voor het probleem echter bij het destructen loopt het mis. Ik krijg dan de volgende error:
Debug error!
Program: ....
DAMAGE: after normal block (#45) at 0x00300090
Ik heb hierop wat gegoogled maar die wijzen allemaal verschillende kanten uiten. Ik vind het ook maar vaag dat ik een geheugenlek zou veroorzaakt hebben terwijl ik gewoon twee STL-functies gebruik en me daar toch niets van geheugenbeheer moet aantrekken want daarom gebruik ik juist STL :-)

Wat code:
C++:
1
2
3
4
5
6
7
8
9
10
/*vakje van een bord*/
#ifndef VAK_H
#define VAK_H

struct vak {
    bool gevuld;
    bool gecontroleerd;
};

#endif

C++:
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
/*Schaakbord*/
#ifndef BORD_H
#define BORD_H

#include "vak.h"
#include <vector>

class bord {
    private:
        std::vector<std::vector<vak> > schaakbord;
        int zijde;

    public:
        ~bord();
        bord(int n);
        bool zetStuk(int rij, int kolom);
        bool controleerStuk(int rij,int kolom);
        void wisStuk(int rij, int kolom);
        void zoekOplossing();
        void zetControleAan(int rij, int kolom);
        void zetControleUit(int rij, int kolom);
        int bord::keerterug(int rij,int kolom);
        void print();
};
#endif

C++:
1
2
3
4
5
6
7
8
9
10
11
//bijhorende constructor en destructor
bord::bord(int n) : schaakbord(n), zijde(n) {
    for(int i=0;i<zijde;i++) {
        for(int j=0;j<zijde;j++) {
            schaakbord[i][j].gevuld=false;
            schaakbord[i][j].gecontroleerd=false;
        }
    }
}

bord::~bord() {/*verwijder alle dynamisch aangemaakte dingen*/}

C++:
1
2
3
4
5
6
7
8
9
10
11
/*Koninginnen probleem: de main (het testprogramma)*/
#include "bord.h"
#include <iostream>
#include <ctime>

int main(void) {
    bord b(8);
    b.zoekOplossing();
    b.print();
    return 0;
}

[ Voor 18% gewijzigd door Verwijderd op 12-06-2004 09:21 ]


  • Infinitive
  • Registratie: Maart 2001
  • Laatst online: 25-09-2023
Deze foutmelding betekent dat je buiten je gealloceerde geheugen hebt zitten schrijven. Alloceer je wel voldoende vakjes op je schaakbord? (dwz: heeft "zijde" de juiste waarde gegeven je "n").

[ Voor 17% gewijzigd door Infinitive op 12-06-2004 09:40 ]

putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]


  • BoAC
  • Registratie: Februari 2003
  • Laatst online: 22-05 23:01

BoAC

Memento mori

DAMAGE: after normal block (#45) at 0x00300090 betekend volgens mij dat je buiten je gealloceerde geheugen loopt of daarbuiten schrijft ;)
bijv:
C++:
1
2
char t[4];
sprinf(t, "test");

Verwijderd

Topicstarter
Infinitive schreef op 12 juni 2004 @ 09:39:
Deze foutmelding betekent dat je buiten je gealloceerde geheugen hebt zitten schrijven. Alloceer je wel voldoende vakjes op je schaakbord? (dwz: heeft "zijde" de juiste waarde gegeven je "n").
Zoiets had ik ook gelezen echter mijn programma loopt goed tot aan de destructor dus ik schrijf nergens in mijn programma buiten mijn dubbele vector anders zou die toch allang daarop gecrashed zijn.
De constructor maakt gewoon een dubbele vector aan met zijden lopend van 0 tot 8 (8 exclusief, dus de lengte is 8 ) ik zie niet in waarom de destructor van vector plots wel buiten het geheugen zou gaan?

[ Voor 3% gewijzigd door Verwijderd op 12-06-2004 09:58 ]


  • Infinitive
  • Registratie: Maart 2001
  • Laatst online: 25-09-2023
Denk wel aan het volgende he: in debugmode wordt er extra geheugen om variabelen gealloceerd. Pas bij het vrijgeven van die ruimte wordt gekeken of dat extra geheugen nog wel in de onbeschreven toestand verkeerd. Dus de fout kan al eerder in je programma zit.

Geeft hij ook al een foutmelding als je alleen Bord b( 8 ) in je main zet?

[ Voor 17% gewijzigd door Infinitive op 12-06-2004 10:04 ]

putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]


Verwijderd

Topicstarter
De fout moet wel ergens eerder zitten want als ik een variabele (zelfs al heeft die niets te maken met dat schaakbord ofzo) wil wegschrijven in het hoofdprogramma crasht hij ook. Maar hoe kan dat dan? Ik alloceer toch helemeel niet manueel dynamisch geheugen?
Nog wat extra code:
C++:
1
//niet relevante code weggehaalt (voegt niets toe aan het probleem)

De oplossing vindt hij, 't is niet de meest ideale methode denk ik I dunno, en ik ga er ook vanuit dat de oplossing bestaat immers dat wist ik. Maar het is me dus om die geheugenfout te doen.

[ Voor 153% gewijzigd door Verwijderd op 12-06-2004 10:56 ]


  • Infinitive
  • Registratie: Maart 2001
  • Laatst online: 25-09-2023
Excuses, door mijn minimale ervaring met C++ zag ik het volgende over het hoofd:
: schaakbord(n), zijde(n)
(ik dacht dat schaakbord en zijde speciale klassen van je waren :X maar dat zijn neem ik aan initialisaties van de membervariabelen schaakbord en zijde?)

Maar dan denk ik dat de fout zit in het volgende:
je maakt wel de eerste dimensie van de schaakbord vector aan (n), maar niet de vectoren die daarin zitten.

[ Voor 122% gewijzigd door Infinitive op 12-06-2004 10:12 ]

putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]


Verwijderd

Topicstarter
Infinitive schreef op 12 juni 2004 @ 10:06:
Excuses, door mijn minimale ervaring met C++ zag ik het volgende over het hoofd:
: schaakbord(n), zijde(n)
(ik dacht dat schaakbord en zijde speciale klassen van je waren :X )

Maar dan denk ik dat de fout zit in het volgende:
je maakt wel de eerste dimensie van de schaakbord vector aan (n), maar niet de vectoren die daarin zitten.
Maar die worden toch wel aangemaakt, anders zou dat programma nooit een oplossing kunnen genereren. Dan zou mijn programma resoluut crashen op schaakbord[rij][kolom]
Die dubbele vector werkt perfect imho, anders zou de constructor al crashen, immers daar wijs ik alle vakjes false toe.
die ": schaakbord(n), zijde(n)" dat zijn inderdaad gewoon initialisaties. dus da's bvb hetzelfde als zijde = n;
en schaakbord(n) maakt gewoon een 2D array aan met hoogte "n"

[ Voor 26% gewijzigd door Verwijderd op 12-06-2004 10:39 ]


Verwijderd

Topicstarter
[quote]Infinitive schreef op 12 juni 2004 @ 10:06:
blabla
[quote]
Ah ge hebt mij toch op het goede been gezet, om een bruikbare matrix te hebben moest ik
C++:
1
2
    for (int m=0;m<n;m++)
        schaakbord[m].resize(n);

toevoegen aan de constructor. Zo kan hij dit bij de destructor wel goed afbreken, anders niet blijkbaar. Het probleem is dus opgelost :)

[ Voor 5% gewijzigd door Verwijderd op 12-06-2004 10:45 ]


  • Juicy
  • Registratie: December 2000
  • Laatst online: 12:10
Ah ge hebt mij toch op het goede been gezet, om een bruikbare matrix te hebben moest ik
C++:
1
2
    for (int m=0;m<n;m++)
        schaakbord[m].resize(n);

toevoegen aan de constructor. Zo kan hij dit bij de destructor wel goed afbreken, anders niet blijkbaar. Het probleem is dus opgelost :)
Dit heeft niet met het afbreken te maken maar juist met het probleem veroorzaakt in het begin ... Je zat namelijk niet gealloceerd geheugen te gebruiken voor de 2e dimensie van je array.

Maar het probleem is opgelost :)

[ Voor 16% gewijzigd door Juicy op 12-06-2004 10:54 ]

-


Verwijderd

Topicstarter
Juicy schreef op 12 juni 2004 @ 10:54:
[...]


Dit heeft niet met het afbreken te maken maar juist met het probleem veroorzaakt in het begin ... Je zat namelijk niet gealloceerd geheugen te gebruiken voor de 2e dimensie van je array.

Maar het probleem is opgelost :)
Maar wat ik niet versta is waarom het programma dan niet crasht als ik dat niet gealloceerd geheugen wil gebruiken, normaal doet hij dat toch nu was dat niet, de computer genereerde zelfs een oplossing.

Maar het probleem is gelukkig opgelost :)

[ Voor 5% gewijzigd door Verwijderd op 12-06-2004 10:57 ]


  • Infinitive
  • Registratie: Maart 2001
  • Laatst online: 25-09-2023
Maar wat ik niet versta is waarom het programma dan niet crasht als ik dat niet gealloceerd geheugen wil gebruiken, normaal doet hij dat toch nu was dat niet, de computer genereerde zelfs een oplossing.
Dat heeft er dus mee te maken met dat er extra ruimte door de debugger om variabelen heen gereserveerd wordt. En als dat niet voldoende is, maar je hebt nog gealloceerde ruimte erna beschikbaar (voor een andere variable bijv), dan kan daar gewoon zonder probleem naar geschreven worden (voor je processor dan). Dat de gevolgen daarvan rampzalig kunnen zijn kan je best wel voorstellen ;)

Dat is dan ook meteen de reden waarom de debugger de extra ruimte reserveerd: zodra je daar iets anders naar schrijft kan hij dit tenminste zien en weet je teminste dat er iets mis is. En verder dan maar hopen dat dit gebeurd voordat je 100K regels code hebt zitten kloppen.
De oplossing vindt hij, 't is niet de meest ideale methode denk ik I dunno, en ik ga er ook vanuit dat de oplossing bestaat immers dat wist ik. Maar het is me dus om die geheugenfout te doen.
Wat voor oplossing strategie gebruik je voor het n konigninnenprobleem? Voor kleine n kan je met een branch en bound algoritme best snel een antwoord vinden.
Check bijv. http://www.cs.uu.nl/docs/vakken/al/algoritmiek2003-7.ppt.

[ Voor 48% gewijzigd door Infinitive op 12-06-2004 12:04 ]

putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]


  • _Squatt_
  • Registratie: Oktober 2000
  • Niet online
Als je de definitie van 'vak' verandert in:
C++:
1
2
3
4
5
struct vak {
    bool gevuld;
    bool gecontroleerd;
    vak() : gevuld( false), gecontroleerd( false) {}
};

Dan kun je de constructor versimpelen naar:
C++:
1
2
3
4
5
bord::bord( int n)
:
    schaakbord(n, std::vector<vak>( n)), // n vectors van n vakken
    zijde(n)
{} // for() loop is niet meer nodig

[ Voor 6% gewijzigd door _Squatt_ op 13-06-2004 02:09 ]

"He took a duck in the face at two hundred and fifty knots."


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Squat z'n oplossing is netjes. Je kan vak ook nog in bord defineeren, dat vind ik altijd iets netter. Dus:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
class bord {
   struct vak { 
       bool gevuld; 
       bool gecontroleerd;
      vak() : gevuld(false), gecontroleerd(false) {} 
   }; 

   bord() {
      ...
   }

};

  • Eelis
  • Registratie: Januari 2003
  • Laatst online: 21-02-2015
.

[ Voor 112% gewijzigd door Eelis op 18-02-2015 19:29 ]


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Eelis schreef op 12 juni 2004 @ 13:34:
[...]of je bios kunnen flashen.
Haha, die kans nadert denk ik wel tot nul :)

  • Eelis
  • Registratie: Januari 2003
  • Laatst online: 21-02-2015
.

[ Voor 107% gewijzigd door Eelis op 18-02-2015 19:29 ]

Pagina: 1