Ist es möglich, ein Segment des Speichers als „außerhalb der Grenzen“ zu markieren, so der Heap-Manager von ihm nicht vergeben ist?

StackOverflow https://stackoverflow.com/questions/4274058

Frage

Bereits heute Morgen Ich habe diese Frage .

einige Zeit Nachdem er dieses Problem zu untersuchen, habe ich entdeckt, was los ist. Ich bin Entsendung dies als eine neue Frage, weil ich denke, es ist interessant genug ist, als ein anderes Thema zu verfolgen. Ich werde diese Frage mit der Antwort aktualisieren (und ein Link zu diesem).

Starten von Unit-Test von Debugger

// Construct object
Object* pObject = new Object(...);
// Pointer value of pObject == 0x05176960

// Lots of other code
// ...

// Destroy object
delete pObject;

// Construct object again
pObject = new Object(...);
// Pointer value of pObject == 0x05560194     /* Different memory location */

Starten von Unit-Test von der Kommandozeile

// Construct object
Object* pObject = new Object(...);
// Pointer value of pObject == 0x05176960

// Lots of other code
// ...

// Destroy object
delete pObject;

// Construct object again
pObject = new Object(...);
// Pointer value of pObject == 0x05176960     /* Same memory location */

Zusammenfassung:

  • Beim Starten des Unit-Tests aus der Befehlszeile , nachfolgende Aufrufe new eine Object (deleteing den vorherigen Object bevor Sie einen neue Zuteilung) zuzuweisen immer kehren die gleiche Adresse im Speicher.
  • Beim Starten des Unit-Tests aus der Debugger , nachfolgenden Aufrufe new eine Object (deleteing den vorherigen Object bevor Sie einen neue Zuteilung) zuzuweisen immer wieder zurückkehren eine eindeutige Adresse im Speicher.

Das Problem ist, dass, weil Zuweisungen von Object bekommen immer die gleiche Adresse im Speicher, wenn über die Befehlszeile zu starten, eine Karte, die ich zugreife, welche die gespeicherten alt Zeiger noch verwendet werden kann und die Test wird nicht abstürzen. Aber ich mag, dass mein Unit-Test zum Absturz zu bringen, wenn der Defekt behebt nicht an seinem Platz ist, um sicherzustellen, dass es nicht stillschweigend nicht versagt und der Defekt nicht zurückkommen.

Es gibt zwei Teile zu meiner Frage:

  1. Warum sollte der Heap-Manager den gleichen Teil des Speichers wiederverwenden, wenn einen Unit-Test von der Kommandozeile starten, aber nicht, wenn ich den Unit-Test aus dem Debugger starten?

  2. Gibt es einen Compiler Einstellung ich auf meinem Testgeschirr verwenden könnte, oder ein Verfahren, kann ich rufen Sie den Heap-Manager von Wiederverwendung eines Abschnitt des Speichers zu verhindern, dass ich gelöscht haben, mir zu erlauben, richtig mein zu schreiben Gerätetest? 1


1 Offensichtlich eine Möglichkeit, dies zu tun, ist das ursprüngliche Objekt, aber der Teil des Codes nicht zu löschen, dass teilt diese in meiner Produktionscode ist, und ich tue dies in Speicherlecks führen würde.

War es hilfreich?

Lösung

Ihr Unit-Test ist fehlerhaft, da es auf undefiniertes Verhalten angewiesen ist. Sie sollen Ihr Gerät zu testen neu schreiben, so dass es nicht auf undefiniertes Verhalten angewiesen ist, in welchem ??Fall es immer, unabhängig davon, passieren wird, wie der Speichermanager Speicher zuweisen entscheidet.

Was Sie tun, ist dies:

Object* pObject = new Object(...);
...
delete pObject;
pObject = new Object(...);
// Use dangling pointer to first object, and if it crashes, the unit test fails
// This is WRONG since a crash isn't guaranteed

Sie sollten stattdessen Umstrukturierung des Unit-Test so funktioniert es wie folgt aus:

Object* pObject = new Object(...);
...
// Check to see if there are dangling references to pObject right before we
// delete it.  If there are, assert() and fail the unit test.
assert(NoDanglingReferences(pObject));
delete pObject;
// Continue on with more tests

Andere Tipps

Sie könnten new und delete mit Ihren eigenen Versionen ersetzen, die das Verhalten haben Sie wollen.

Zunächst einmal - nicht in einem „normalen“ Speicher-Manager. Sobald Sie ausplanen Speicher übergeben Sie Eigentum an sie an den Speicher-Manager und dieser kann sie wiederverwendet werden.

Sie könnten schreiben einen benutzerdefinierten Manager als Benutzer Andreas Brinck schlägt , aber was würde es tun? Dabei spielt es keine Handwerk Speicher aus der Luft, es fordert sie von irgendwo wie CRT-Heap oder Betriebssystem Heap.

Szenario A. Es ist nicht Speicher auf die zugrunde liegenden Haufen zurückkehren würde -. Sie werden ein Leck haben und den Speicherblock wird nach wie vor in den Adressraum abgebildet werden, und es wird zugänglich sein

Szenario B. Es wird Speicher zurück zum Heap zugrunde liegen - dann, wenn Ihr mananger versucht Speicher wieder die zugrunde liegenden Heap diesen Block wieder zurückkehren kann zuzuteilen. Auch wissen Sie nicht, was die zugrunde liegenden Haufen machen, wenn Sie Speicher zu ihm zurückkehren. Es könnte es machen Unmapped oder nicht -. So dass Zugriff auf den Speicher abstürzen oder nicht

Das Endergebnis ist, Sie verschraubt sind. Der Versuch, nicht definiert zu testen Verhalten wird nicht sehr produktiv sein.

Dies ist ein Beispiel für ein undefiniertes Verhalten. Weder C ++ oder die Heap-Manager definieren, wie Speicher zugewiesen werden sollen. Sie können nicht auf entweder Speicher wiederverwendet verlassen wird oder nicht wiederverwendet werden. Wenn Sie so etwas wie in dem oben tun, gibt es keine Möglichkeit, ob oder nicht zurück der Zeiger zu bestimmen oder Wechsel von dem ersten zugewiesen werden anders sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top