Beschädigung des Heaps
-
Ich habe zur Übung eine eigene Vektor-Klasse geschrieben (nach dem Buch TICPP). Jetzt bekomme ich die folgende Fehlermeldung und werde daraus überhaupt nicht schlau.
HEAP[0112.exe]: Heap block at 003B80E8 modified at 003B842C past requested size of 33c
Windows hat einen Haltepunkt in 0112.exe ausgelöst.Dies kann auf eine Beschädigung des Heaps zurückzuführen sein und weist auf ein Problem in 0112.exe oder in einer der geladenen DLLs hin.
#include "vector.h" #include "fraction.h" const int increment = 100; vector::vector(int sz) { size = sz; quantity = 0; storage = 0; next = 0; } void vector::push_back(void* element) { if (next >= quantity) inflate(increment); int startBytes = next*size; // cast element to unsigned char array unsigned char* e = (unsigned char*)element; for (int i = 0; i < size; i++) storage[startBytes+i]=e[i]; next++; } void vector::inflate(int increase) { int newQuantity = quantity + increase; int newBytes = newQuantity * size; int oldBytes = quantity * size; unsigned char* b = new unsigned char[newBytes]; for (int i = 0; i < oldBytes; i++) b[i] = storage[i]; // HEAP-Error?? delete []storage; storage = b; quantity = newQuantity; } vector::~vector() { //HEAP error?? if (storage != 0) delete[] storage; }
-
Hallo,
was mir gerade auffaellt, size wird gar nicht neu gesetzt...oder uebersehe
ich da grad was?gruss
v R
-
Size steht hier für die größe eines Elements und wird daher nur am Anfang initialisiert: vector(sizeof(foo));
-
Fehler sehe ich erstmal keine. Welche Funktionen gibt es denn sonst noch in der Klasse? Bzw. versuche ein Minimalbeispiel zusammenzustellen, welches den Fehler verursacht.
-
Hallo,
ich habe gerade das gleiche Problem bekommen. Habe die Klasse vector aber nicht selber geschrieben, sonder verwende std::vector.
Irgendeine Idee?
Danke!
mfg,
shed
-
shed schrieb:
Irgendeine Idee?
Bereichsüberschreitungen?
vector::op[] überprüft nicht, ob es einen legalen Index bekommt - wenn du einen negativen Wert oder einen Wert >=size() übergibst, erzeugst du undefiniertes Verhalten. Und das kann im Ernstfall bedeuten, daß du wichtige Daten des Heap-Managers (oder schlimmeres) pulverisierst.
-
ich verwende eigentlich nur vector.push_back(), vector.pop_back() und vector.at(),
d.h gebe ich ihm ja selbst keinen index mit.Muss ich da trotzdem aufpassen?

-
hab ich bei stacks das gleich problem?
Bzw. gibt es noch andere Möglichkeiten wann der Fehler auftreten kann außer bei verwendung eines vectors?
-
Der Fehler kann (naturgemäß) immer dann auftreten, wenn du auf dem Heap hantierst. Btw, es ist noch nicht einmal gesagt, daß der vector/stack den Fehler verursacht - viel wahrscheinlicher ist es, daß du von einem anderen Zeiger aus die Daten des vector's zerstört hast.
(Zeig doch mal etwas Code)
-
Und das kann im Ernstfall bedeuten, daß du wichtige Daten des Heap-Managers (oder schlimmeres) pulverisierst.
Was ist denn ein Heap-Manager ?!
-
Na, was denkst du ;)?
Der Heap-Manager ist derjenige, der sich um die Speicherreservierungen auf dem Heap (new/delete oder malloc/free) kümmert und dafür sorgt, daß jeder soviel Speicher zugewiesen bekommt, wie er benötigt.
-
Das habe ich vermutet, jedoch hat mich die Aussage "Heap Manager zerstören" schon etwas stutzig gemacht ! Wie sollte man den Heap - Manager "zerstören" können ?
-
Indem Du einen Teil des Speicherbereichs überschreibst in dem new und delete zur runtime liegen...

greetz, Swordfish
-
Ich habe hier eine ganz wage vermutung. Setz mal um deine beiden
delete[] storage;eine if-Abfrage, dass das ganze jeweils so aussieht:
if (storage != 0) { delete[] storage; }Ich lese nähmlich aus deiner Zeile hier:
unsigned char* b = new unsigned char[newBytes];Dass deine storage-variable ein Pointer auf unsigned char ist, was ok ist, aber diese Zeile hier im konstruktor:
storage = 0;Setzt eben diesen Pointer auf 0 (oder besser: NULL), wodurch es natürlich zum Fehler kommt, wenn du versuchst auf storage ein delete anzuwenden, so lange noch keine gültige Adresse dahinter liegt.
Ich hoffe, es hilft was.
Grüße
FloFri
-
delete[]erkennt 0-Pointer selbst. Einif(x) delete[] x;ist daher nicht nötig.Wenn du Probleme mit dem Heap hast, solltest du mal Valgrind benutzen oder wo das nicht verfügbar ist DUMA
-
mikey schrieb:
Das habe ich vermutet, jedoch hat mich die Aussage "Heap Manager zerstören" schon etwas stutzig gemacht ! Wie sollte man den Heap - Manager "zerstören" können ?
Da hast du etwas missverstanden - du zerstörst nicht "den Heap-Manager", sondern "wichtige Daten des Heap-Managers" (z.B. seine Notizen, wie lang jeder angeforderte Speicherbereich war).