Abgeleitete Objekte durch einen Basisklassenzeiger mit new reservieren



  • Aaaalso, ich habe folgenden Code, bei dem ich mittels eines Basisklassenzeigers verschiedene "Einheiten"typen alloziere. Passt auch soweit so gut, es wurde bisher auch 1000-mal ohne Fehler kompiliert und nun kommt bei dem Code

    case 1:
    		contBanner="Bitmaps\\Archer.bmp";
    		pActualSoldierType=new CArcher[contSize]; 
    //Beim Auskommentieren der Allozierung, geht alles normal, also liegts daran
    		break;
    

    plötzlich eine fette Errorbox mit gelaber à la
    "Debug Assertion Failed!
    Programm: <path>
    File: dbgheap.c
    Line: 1017

    Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)

    FOr Information how your programm can cause blabla...

    (Press Retry to Debug your application) "

    Und beim Debuggen, komme ich dann zu folgender Stelle, die mir anzeigt, dass was falsch ist 😉 :
    "0043247A int 3"
    und wenn alles normal gehen würde, wäre dieser int ja 0.

    Was kann ich da tun??



  • Du zerstörst den Freispeicher irgendwann vorher (über Arraygrenze hinausgeschrieben o.ä.), was die new-Operation glücklicherweise erkannt hat. Mit dem Code den du gepostet hast hat das nichts zu tun.
    Der int 3 ist einfach der Assemblerbefehl für einen Breakpoint, hat damit also auch nichts zu tun 😉 Das ist nur dazu da, dass du, wenn die Assertion fehlschlägt, direkt im Debugger landest.



  • hmm naja das glaub ich nich, weil ich immer schön allozier, aber ich schau mal besser noch nach...

    Hier is der Code der gesamten Funktion:, vielleicht hilft das noch weiter 😉

    void CContingent::setContingent(int newContType, unsigned long int newsize)
    {
    	contSize=newsize;
    	delete [] pActualSoldierType;
    	switch(newContType)
    	{
    	case 1:
    		contBanner="Bitmaps\\Archer.bmp";
    		pActualSoldierType=new CArcher[contSize]; 
    		break;
    	case 2:
    		contBanner="Bitmaps\\Crossbowman.bmp";
    		pActualSoldierType=new CCrossbowman[contSize]; 
    		break;
    	case 3:
    		contBanner="Bitmaps\\Lance.bmp";
    		pActualSoldierType=new CLance[contSize]; 
    		break;
    	case 4:
    		contBanner="Bitmaps\\Footman.bmp";
    		pActualSoldierType=new CFootman[contSize]; 
    		break;
    	case 5:
    		contBanner="Bitmaps\\Knight.bmp";
    		pActualSoldierType=new CKnight[contSize]; 
    		break;
    	default:
    		cout<<endl<<endl<<endl<<red<<"UNERLAUBTE KONTINGENTZUWEISUNG!"<<defaultrgb<<endl<<endl<<endl;
    		delay(5); break;
    	}
    }
    


  • Wird für pActualSoldierType denn noch woanders im Programm ein new ausgeführt? Wenn nicht, haste beim ersten Aufruf der Funktion ein Problem...



  • Öhm nein, ich hab nur im Ctor die eine NULL-Setzung des Pointers vorgenommen
    pActualSoldierType=NULL;
    Aber sonst nix.
    Warum hab ich da ein Problem(anscheinend eben dieses 😉 ), wenn ich vorher noch kein anderes new hatte???

    Wenns NULL ist, dann dürfte er doch keine Probleme damit haben..



  • Herr der Dinge schrieb:

    hmm naja das glaub ich nich, weil ich immer schön allozier, aber ich schau mal besser noch nach...

    Hier is der Code der gesamten Funktion:, vielleicht hilft das noch weiter 😉

    Wie ich schon sagte, das hat mit dem geposteten Code nichts zu tun. new stolpert einfach darüber, dass die Verwaltungsinformationen des Freispeichers irgendwo unsinnige Werte haben, was eigentlich (wenn man mal Bugs von MS-Seite ausschließt) nur bedeuten kann, dass du irgendwo über die Grenzen eines von dir belegten Blockes hinaus geschrieben hast.



  • Ist der Destruktor der Basisklasse dieser ganzen Typen (CArcher usw.) vielleicht nicht virtuell?

    EDIT: Je mehr ich drüber nachdenke, desto mehr vermute ich, dass das gar nicht klappen kann. Arrays polymorph ... das geht in die Hose.



  • Hmm naja den ganzen Abgeleiteten Klassen hab ich keinen expliziten Dtor verpasst, nur nen Ctor.
    Aber der Basisklassenzeiger wird dann automatisch am Ende gelöscht, also eigenlich auch sämtliche Elemente auf die er zeigt der abgeleiteten Klassen.

    Edit:
    Ich kann das ja auch machen, indem ich in der Kontingent-Klasse für jeden Einheitentyp einen Pointer setz, aber das wäre die letzt Lösung, die mir einfiele, da ich so etwas eigentlich nicht beabsichtig hab...



  • Hmm naja den ganzen Abgeleiteten Klassen hab ich keinen expliziten Dtor verpasst, nur nen Ctor.

    Ich rede von virtuellen Destruktoren.

    Aber das was ich unter EDIT geschrieben habe ist wahrscheinlich wichtiger.



  • Bashar schrieb:

    EDIT: Je mehr ich drüber nachdenke, desto mehr vermute ich, dass das gar nicht klappen kann. Arrays polymorph ... das geht in die Hose.

    Jep!

    Siehe auch More Effective C++ Item 3 "Never Treat Arrays Polymorphically"



  • So, ich habs etz "normal" gemacht für jeden Typ einen Zeiger und dann allozieren, sonst gehts aber jetzt kommt die Fehlermeldung immer noch...
    Buhuhuhu 😞 (Das ist doch nun keine Polymorphie mehr oder 😉 ?)
    Ich hab überall brav gelöscht etc....Ich versteh das einfach nicht!

    Kann das irgendwie weiterhelfen?

    memory check error at 0x008E19EC = 0xDD, should be 0xFD.
    memory check error at 0x008E19ED = 0xDD, should be 0xFD.
    memory check error at 0x008E19EE = 0xDD, should be 0xFD.
    memory check error at 0x008E19EF = 0xDD, should be 0xFD.


Log in to reply