halde Test cases

Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.

halde Test cases
Heya,

gibt mal wieder Test cases… :smiley:

https://www.milanstephan.de/halde-test-nudelsalat.php

3 Likes

Als Tipp, leg das doch einfach in dein [m]pub[/m]-Verzeichnis in deinem Home im CIP. Dann kommt man aus der Uni leicht ran und kann sich die Datei bequem kopieren.

4 Likes

Sau geil! Besten Dank wieder mal :slight_smile:

lg Flo


Danke fuer die Testcases. Ich habe gleich eine Frage dazu.
Welche errno muss denn im Fall von malloc(0) gesetzt werden? Denn ich setzte erno = ENOMEN, aber der Testfall sagt, dass ich die errno nicht gesetzt habe.
Also nehme ich mal an, dass errno da einen anderen Wert haben muss?


Keine? [m]malloc(0)[/m] ist kein Fehler. Siehe dazu auch der Abschnitt „Return Value“ in [m]man 3p malloc[/m].


Das hatte ich durchgelesen und unter „Return Value“ steht: „On error, these functions return NULL. NULL may also be returned by a successful call to malloc() with a size of zero“.
Ok… jetzt wollte ich hier gerade das Argumentieren anfangen und habe dabei gemerkt, dass du Recht hast, weil der zweite Satz impliziert, dass malloc(0) kein Fehler ist.

Ich habe trotzdem noch eine Frage zum Test 18: Der Test schlaegt bei mir mit FAIL(‚9‘) fehl, aber ich verstehe nicht ganz warum, da ich den Gedanken des Tests nicht verstehe. In Kurzfassung:

char *ptr1 = malloc(32);
for(int i = 0; i < 32; i++) {
	ptr1[i] = '*';
}
char *ptr5 = realloc(ptr1, 100);
char different = 0;
for(int i = 32; i < 32 + MBLOCKSIZE; i++) {
	if(ptr5[i] != ptr1[i]) different = 1;
}
if(different == 0) FAIL('9');

Ich weiß nicht, was das genau testen soll, es sieht aber auf jeden Fall ziemlich kaputt aus. Der Zugriff auf [m]ptr1[i][/m] nach dem [m]realloc[/m] ist ein use-after-free, das ist kaputt.


Das ist zwar kaputt, aber so beabsichtigt, izibi. :wink:

Der Test soll prüfen, wie groß der kopierte Bereich ist. Wären die Bereiche gleich hieße das, dass von ptr1 mehr als 32 Bytes gelesen und in den neuen Bereich kopiert wurden.
Wenn ptr1 jetzt am Ende von memory liegt, kann es passieren, dass man über das Ende von memory hinaus liest. Auch, wenn ptr1 nicht am Ende liegt, werden unnötige Daten kopiert, die Verwaltungsblöcke, Daten von anderen Blöcken, z.B. nen Private Key oder sonst was enthalten könnten.^^ → Böse!

Beispiel: X=Verwaltungsblock, .=frei, A=zugewiesener Block 1, B=zugewiesener Block 2, r=read, w=write

[code]XAAAAAAAAAAAAAAAAAAAAAAAAXBBBBBBB

nach free(A)
X…XBBBBBBB

C=realloc(B, fooMehrAlsGrößeVonB)
XCCCCCCCCCCCCCCCX…X…
wwwwwwwwwwwwwww rrrrrrrrrrrrrrr
^da haben wir den Salat, das sollte nicht mehr gelesen werden![/code]

Edit:
@rudis: Gute Idee, mach ich später! :slight_smile:


Vielen Dank. Jetzt funktionert es :slight_smile:


Ich glaube izibi meint Folgendes:

Da dies in deinem Beispiel-Code der Fall ist, duerftest du (in Zeile 8) nicht davon ausgehen, dass ptr1 noch auf sinnvolle Dinge zeigt.


Das verstehe ich jetzt nicht. Ich sagte nur, dass der Zugriff auf [m]ptr1[i][/m] undefined ist (außer [m]ptr1 == ptr5[/m], was zwar ein erlaubtes Verhalten von [m]realloc[/m] ist, wovon man aber im Allgemeinen nicht ausgehen kann). Dazu kommt natürlich hinzu, dass der Speicher, den du dann aus [m]ptr5[/m] hinten liest, undefinierten Inhalt hat. Also rein theoretisch dürfte da sogar zufällig das gleiche stehen. Wird höchstwahrscheinlich nicht der Fall sein, wäre aber erlaubt.

Aber ja, ist problematisch, wenn du sowas testen willst, da du direkt auf die Ursache dafür nicht testen kannst. Also in dem Fall, ob es über den alten Speicherbereich hinausliest und kopiert.


Ich versteh’ jetzt nicht, dass du 's nicht verstehst 0.o
Wie auch immer: Ich wollte auf einen deiner Punkte eingehen und habe diebzgl. (denke ich) den passenden Part aus der entspr. man-Page zitiert … koennte aber auch sein, dass ich grade auf 'm Schlauch stehe.

edit:
narf - ich hab’ einfach tomaten auf den augen gehabt - wollte natuerlich folgenden part zitieren:


Bei der Aufgabe soll [m]realloc[/m] sich in jedem Fall einen neuen Block mit der gewünschten Größe holen ([m]malloc[/m]), den alten Block dort hinein kopieren ([m]memcpy[/m]) und dann den alten Block [m]free[/m]n. Sogar, wenn der neue Block kleiner ist.

void *a = malloc(50); void *b = realloc(a, 100);
soll beim Kopieren aber keine 100 Bytes von a lesen, sondern nur 50. ← Test 18

Genau wie

void *a = malloc(150); void *b = realloc(a, 100);
auch keine 150 Bytes lesen soll, sondern 100. ← Test 19

Sprich, [m]memcpy[/m] soll (Minimum der beiden Blockgrößen) Bytes kopieren.


Vielen Dank, spitzen Test cases! :wink:


Update :wink: