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 dirstore->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,
seldondacht 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.