Komisches Pointerverhalten und Fehlermeldung bei free

Bullz

Mitglied
Hier handelt es sich um ein Codebeispiel das ich modifiziert habe. Früher gab es eine *hilf Pointer der statt dem *memptr raufgezählt wurde. Zum Schluß wurde dann über eine schleife mit printf die Inhalte der Pointervariablen memptr ausgelesen.

Meine Aufgebenstellung für mich war es das alles nur mit einem Pointer hinzubekommen.

Erwarten tue ich 2 1 0.
Bekommen tue ich 2 rießige Zahlen und eine 0. Die 0 passt wenigstens schon mal

Beim Debuggen ( und nicht beim normalen ausführen ) fliegt er auch beim free raus ...
No source available for "ntdll!TpWaitForAlpcCompletion() at 0x77c80575 warum auch immer. Böse Pointer :(
Ich Code dient nur Testzwecken.

Code:
/* bspl0099.c */
#include <stdlib.h>
#include <stdio.h>

#define MAX_ZAHL 2

int main() {
	double *memptr,*hilf;
	int i;
	memptr = (double *) malloc(MAX_ZAHL * sizeof(double));
	//hilf = memptr;
	if(memptr == NULL) {
		printf("\nNicht genuegend Speicher!");
		exit(1);
	}
	printf("\nSpeicher fuer %i double-Werte ok!\n",
				MAX_ZAHL);
	for(i=0; i<=MAX_ZAHL; i++) {
		*memptr=i;
		memptr = memptr+1;
	}
	memptr--;


	for(i=3; *memptr != 0; i) {
		printf(" %f",memptr[i]);
		memptr--;
	}
	printf(" %f",memptr[i]);
	free(memptr);
	printf("\nSpeicherplatz wieder freigegeben!");
	return 0;
}
 
Hallo,

Die erste for-Schleife läuft schon einmal bis <= MAX_ZAHL --> du gehst über deinen reservierten Speicherbereich hinaus!

Dann setzt du in der nächsten Schleife das i auf 3. memptr ist aber noch immer eins über dem letzten Element. Mit memptr[3] greifst du jetzt auf das vierte Element nach memptr zu. Das bedeutet du bist 5 Element nach deinem reservierten Speicherplatz und gibst das aus.

Problem bei free(): Warscheinlich gibt es in deinem Speicher zufällig noch irgendwo eine andere 0 und bei dieser wird die Schleife dann beendet und beim Aufruf von free() gibt es dann natürlich einen Absturz, weil dieser Platz nie reserviert wurde.


Am besten nimmst du Papier und Bleistift zur Hand und zeichnest dir das Programm auf. Denk noch einmal alle Schritte genau durch und du wirst die von mir beschriebenen Fehler ausbessern können. :)

Lg
 
okay thx aber eins verstehe ich nicht.

warum darf ich einen Pointer nicht free"en" wenn ich ihn 3 mal raufzähle und 3 mal runterzähle ? Zum Schluss zeigt er auf die gleiche Stelle wie am Anfang oder ist das free"en" von Pointern die schon mal rauf/ runtergezählt worden ein Unding in c ?
 
Hallo Bullz

Der Grund warum er beim free 'rausfliegt' liegt vermutlich daran, dass mit der Debugruntime in der Regel bei Speicheroperationen (Allokation, Freigabe) die Integrität des Heaps überprüft wird. Da kann man dann häufig rausfinden, ob du über die Grenzen eines allozierten Bereichs herausgeschrieben hast und entsprechend wird dann ein Heap Failure reportet.

Viele Grüsse
Cromon
 
Bitte lies dir noch einmal meinen Beitrag genau durch. Es ist nicht sichergestellt, dass dein Pointer dreimal hinauf- und dreimal hinuntergezählt wird.

Lg
 
Ich schalte mich dann auch mal ein:

  • Es ist sehr gefährlich, Pointer per Addition/Subtraktion zu verändern
  • Deine for-Schlaufe auf Zeile 25 ist pure Verwirrung
  • Du mischst double und int
  • memptr[i] ist dasselbe wie *(memptr+i). Danach memptr zu subtrahieren ist... seltsam. (Zeile 26/27)

C:
/* bspl0099.c */
#include <stdlib.h>
#include <stdio.h>
 
#define MAX_ZAHL 2
 
int main() {
    double *memptr = NULL;
    int i = 0;
    memptr = (double *) malloc((MAX_ZAHL+1) * sizeof(double));   //Sonst hast du nur 2 Zahlen.
    if(memptr == NULL) {
        printf("\nNicht genuegend Speicher!");    //Gibt theoretisch noch andere Gründe.
        exit(1);
    }
    printf("\nSpeicher fuer %i double-Werte ok!\n",
                MAX_ZAHL+1);  //Wieder: Du willst 3 Zahlen.
    for(i=0; i<=MAX_ZAHL; i++) {
        memptr[i] = i;
    }
 
    for(i=2; i >= 0; i--) {
        printf(" %f",memptr[i]);
    }
    free(memptr);
    printf("\nSpeicherplatz wieder freigegeben!");
    return 0;
}
Ungetestet.

Gruss
cwriter
 
Also danke für die Hilfe. Bin mal soweit gekommen dass ich das Ergebnis bekomme habe was ich wollte. Nur beim free schmiert er mir beim Debuggen immer ab und ich verstehe nicht warum ... muss compiler Fehler sein ;) joke

Ich bekomme eine Speicheradresse mit Platz für 3 Int also 12 Byte

0xae1850
0xae1854
0xae1858

diese zählt er 2 mal wieder runter

0xae1854
0xae1850

und dann probiert er ein free auf 0xae1850. Peng ... :(


Code:
/* bspl0099.c */
#include <stdlib.h>
#include <stdio.h>

#define MAX_ZAHL 2

int main() {
	int *memptr;
	int i;
	memptr = (int *) malloc(MAX_ZAHL * sizeof(int) + 1);
	if(memptr == NULL) {
		printf("\nNicht genuegend Speicher!");
		exit(1);
	}
	printf("\nSpeicher fuer %i double-Werte ok!\n",
				MAX_ZAHL + 1);

	for(i=0; i<=MAX_ZAHL; i++) {
		*memptr=i;
		if(i ==2)
			continue;
		memptr = memptr+1;
	}
	i--;

	while(*memptr != 0) {
		printf(" %d",*memptr);
		memptr--;
	}
	printf(" %d",*memptr); //   memptr[2] = 2  memptr[1] = 1 memptr[0] = 0
	free(memptr);
	printf("\nSpeicherplatz wieder freigegeben!");
	return 0;
}

p.s wie kann ich hier c-code Quoten in farbe ?
 
Zuletzt bearbeitet:
Also danke für die Hilfe. Bin mal soweit gekommen dass ich das Ergebnis bekomme habe was ich wollte. Nur beim free schmiert er mir beim Debuggen immer ab und ich verstehe nicht warum ... muss compiler Fehler sein ;) joke
:confused:
Dein Bildschirm muss defekt sein und nur jeweils zwei bis drei Wörter eines Posts anzeigen können.
Sorry, wir alle hier helfen gerne, aber wenn du die Beiträge nicht liest...
;-]

Also nochmals:
1. Die Speicheradressen kannst du aufzählen, soviel du willst. Diese werden immer 4-Byte-Schritte sein, weil ein int 32 bit gross ist.
2. Du veränderst noch immer den Pointer selbst, und solange du nicht einen guten Grund dafür hast, würde ich das tunlichst unterlassen.
3. Dein neues malloc() macht so überhaupt keinen Sinn. Punkt vor Strich... Du allozierst einfach 2 * 4 + 1 (=9) Bytes anstatt (2+1)*4 (=12) Bytes.
4. Dein i-- auf Zeile 24 macht keinen Sinn.
5. Dein
C:
while(*memptr != 0) {
        printf(" %d",*memptr);
        memptr--;
    }
ist ein ganz heisses Spielchen, könnte aber funktionieren.
6. Das continue; auf Zeile 20/21 ist auch ein "Hä" wert. break wäre logischer.

Das "Peng" kommt von Punkt 3.

Farbigen Code kriegst du mit [c]...[/c] hin.

Gruss
cwriter
 
:confused:
Dein Bildschirm muss defekt sein und nur jeweils zwei bis drei Wörter eines Posts anzeigen können.
Sorry, wir alle hier helfen gerne, aber wenn du die Beiträge nicht liest...
;-]

Nur weil ich die Relativitätstheorie auf wiki lese kann ich sie noch lange nicht ;) aber der Smilie hat mal super gepasst und hat mich zum lachen gebracht. Nachdem ich das mit dem View Memory in Eclipse rausgefunden habe ... deine Bemerkungen werde ich alle einbauen und eine Version erstellen wo ich ohne Pointer raufzählen arbeite ...

Das einzige was mich jetzt noch vor ein Problem stellt ist das ich selbst mit view Memory noch nicht " Idiotensicher " erkenne kann ob ich innerhalb meines Speicherbereichs gearbeitet habe... gibt da eine Lösungen außer externe Software / Addons ?

C:
#define MAX_ZAHL 2

int main() {
	int *memptr;
	int i;
	memptr = (int *) malloc((MAX_ZAHL + 1)* sizeof(int) );
	if(memptr == NULL) {
		printf("\nNicht genuegend Speicher!");
		exit(1);
	}
	printf("\nSpeicher fuer %i double-Werte ok!\n",
				MAX_ZAHL + 1);

	for(i=0; i<=MAX_ZAHL; i++) {
		memptr[i]=i;
		if(i ==2)
			break;
	}

	while(memptr[i] != 0) {
		printf(" %d",memptr[i]);
		i--;
	}
	printf(" %d",memptr[i]); 
	free(memptr);
	printf("\nSpeicherplatz wieder freigegeben!");
	return 0;
}
 
Zuletzt bearbeitet:
Das einzige was mich jetzt noch vor ein Problem stellt ist das ich selbst mit view Memory noch nicht " Idiotensicher " erkenne kann ob ich innerhalb meines Speicherbereichs gearbeitet habe... gibt da eine Lösungen außer externe Software / Addons ?
Bei C/C++ bist du für die Speicherverwaltung selbst verantwortlich und musst beim Coden auf die Einhaltung von Speichergrenzen, Arraygrößen etc. selbst achten. Wenn da was sich schiefgeht wird sich dein Programm schon melden, sprich: crashen.

Wenn es nicht unbedingt reines C sein muss, kann man mit C++ und dynamischen STL-Containern die fehlerträchtige selbstgemachte Speicherallokierung umgehen.

Gruß
MCoder
 

Neue Beiträge

Zurück