DAMAGE: after normal block(xx) at (0xyy)



  • Du schreibst irgendwo in Speicher, der dir nicht gehört. Dass passiert meistens wenn man irgendwas mit new[] gefrickelt hat statt Container zu benutzen, und mehr in den Speicherbereich reingeschrieben hat als reinpasst. Beim delete merkt die Runtime das und bringt diese "damage after normal block"-Fehler.
    Die genaue Stelle ist oft nicht offensichtlich. Die Kristallkugel sagt, dass du dir

    store->Write(node->Path().Page(), buf);
    

    mal genauer anschauen sollst.



  • Meine Verteidigung zu der sehr langen Funktion ist, dass ich den Code nicht selber geschrieben habe, sondern einfach nur verwenden möchte. Ich habe auch nicht besonders viel C++ Erfahrung, da ich bis jetzt immer alles in Java implementiert habe. Dort muss man sich ja auch nicht mit der Speicherfreigabe beschäftigen.
    Der Aufruf store->Write(node->Path().Page(), buf) führt hier hin.

    void 
    MTfile::Write(GiSTpage page, const char *buf)
    {
    	if(IsOpen()) {
    		lseek(fileHandle, page*PageSize(), SEEK_SET);
    		write(fileHandle, buf, PageSize());
    		IOwrite++;
    	}
    }
    

    Wenn ich die write-Methode hier richtig interpretiere, dann wird in fileHandle der Inhalt von buf hineingeschrieben, oder? Dann kann hier buf nicht übergelaufen sein. Auch der zweite Aufruf node->Pack(buf), in dem der buf eine Rolle spielt macht für mich den Eindruck, als würde buf dabei nicht verändert.

    void 
    GiSTnode::Pack(char *page) const
    {
    	// Pack the header
    	GiSTheader *h=(GiSTheader *) page;
    
    	h->level=Level();
    	h->numEntries=NumEntries();
    	h->sibling=Sibling();
    
    	int fixlen=FixedLength();
    	GiSTlte *ltable=(GiSTlte *)(page+tree->Store()->PageSize());
    	GiSTlte ltptr=GIST_PAGE_HEADER_SIZE;
    
    	for(int i=0; i<numEntries; i++) {
    		GiSTcompressedEntry compressedEntry=(*this)[i]->Compress();
    
    		if(fixlen) assert(fixlen==compressedEntry.keyLen);
    		// Copy the entry onto the page
    		if(compressedEntry.keyLen>0) memcpy(page+ltptr, compressedEntry.key, compressedEntry.keyLen);
    		memcpy(page+ltptr+compressedEntry.keyLen, &compressedEntry.ptr, sizeof(GiSTpage));
    		// Be tidy
    		if(compressedEntry.key) delete compressedEntry.key;
    		// Enter a pointer to the entry in the line table
    		if(!fixlen) *--ltable=ltptr;
    		ltptr+=compressedEntry.keyLen+sizeof(GiSTpage);
    	}
    	// Store extra line table entry so we know last entry's length
    	*--ltable=ltptr;
    }
    

    Für mich sieht das also so aus, als wird buf in GiST::WriteNode erstellt, dann passiert nicht mehr viel mit ihm und dann wird er dort wieder gelöscht.



  • Simpson84 schrieb:

    Meine Verteidigung zu der sehr langen Funktion ist, dass ich den Code nicht selber geschrieben habe, sondern einfach nur verwenden möchte.

    Das ist keine Entschuldigung 😉 Man sollte keinen Code verwenden, den man nicht versteht.
    Wenn man ihn aber versteht, gibts keine Entschuldigung, ihn nicht etwas übersichtlicher zu machen (d.h. in kleinere Funktionen zu zerlegen) 😉



  • Ich habe in den Sourcecode mal mehrere assert(_CrtCheckMemory()); eingefügt und dabei crashed das ganze in der Pack-Methode direkt nach

    // Copy the entry onto the page
    if(compressedEntry.keyLen>0) memcpy(page+ltptr, compressedEntry.key, compressedEntry.keyLen);
    

    Sieht jemand die Ursache dafür?



  • Ein Debugger könnte dir sicher besser weiterhelfen.



  • char *buf=new char[store->PageSize()]; 
    
        //...
    
        delete[] buf; // <-- statt delete buf;
    


  • So ein einfacher Fehler und keiner sieht ihn ^^

    Ich hab ihn auch nicht gesehen.

    gw,
    seldon



  • _))) schrieb:

    So ein einfacher Fehler und keiner sieht ihn ^^

    Ich hab ihn auch nicht gesehen.

    gw,
    seldon

    dacht ich mir auch... -.-



  • Oh ja, da lag ich wohl voll daneben. Das wusste ich gar nicht, dass so auch der Fehler kommen kann.



  • Besten Dank!
    Das war mir noch gar nicht aufgefallen. Das alleine war zwar noch nicht die Lösung, da auch noch inhaltlich im Programm was schief lief.


Anmelden zum Antworten