C realloc() Problem

nailos

Lt. Junior Grade
Registriert
Juli 2010
Beiträge
489
Hallo :)

habe zwei Probleme mit realloc(), erstens wird der reservierte Speicher nicht größer nach dem reallocieren und zweitens kommt nach dem dritten reallocieren ein Fehler.

Folgender Code:

Code:
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <assert.h>

#define LEN 10

typedef struct{
	int i;
	char s[LEN];
}str;

void fkt(str *strptr){
	int ibuf;
	char sbuf[LEN];
	
	int rd, i = 0;
	char ende = 'j';
	do{
		if(ende == 'n'){
			strptr = (str *)realloc(strptr, sizeof(*strptr) + sizeof(str));
			assert(strptr != NULL);
			//hier lasse ich mir die Größe des reservierten Speichers anzeigen
			printf("DEBUG: size: %lu\n", sizeof(*strptr)/sizeof(str));
			i += 1;
		}
		
		do{
			char c;
			printf("Gib i und s ein.\n");
			rd = scanf("%d %s", &ibuf, (char*)sbuf);
			do{
				c = getchar();
			}while(c != '\n');
		}while(rd != 2);				
		strptr[i].i = ibuf;
		strncpy(strptr[i].s, sbuf, LEN);
		
		do{
			char c;
			printf("Ende? j/n\n");
			rd = scanf("%c", &ende);
			do{
				c = getchar();
			}while(c != '\n');
		}while(rd != 1);
	}while(ende == 'n');
}

void prs(str *strptr){
	int i;
	for(i = 0; i < (sizeof(*strptr)/sizeof(str)); i++){
		printf("Ausgabe: i = %d; s = \"%s\"\n", strptr[i].i, strptr[i].s);
	}
}

int main(void){
	str *sptr = malloc(sizeof(str));
	
	fkt(sptr);	
	prs(sptr);
	
	free(sptr);
	sptr = NULL;
	
	return 1;
}

Ist das ein Fehler drinn, oder habe ich einfach etwas nicht beachtet? Hoffe ihr könnt mir schnell helfen.

LG nailos
 
Zuletzt bearbeitet:
strptr hat die größe von str, also gibt dir realloc() immer Speicher für 2 Strukturen raus (oder halt NULL). Das willst du doch sicher nicht, oder?

Besser wäre sowas wie realloc(ptr, x * sizeof(ptr)), wobei x halt die Anzahl Strukturen ist, für die du Speicher haben willst.
 
Kleiner Hinweis:

sizeof ist ein präprozessor-operator, er kann nicht die größe von dynamischen arrays im heap ermitteln.
 
sizeof() hat mit dem Präprozessor wenig zu tun, und selbst wenn es doch so wäre, spielt es hier keine Rolle.

Code:
asdf@chelloveck:/home/asdf/src$ gcc -E ojiasdf.c
# 1 "ojiasdf.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "ojiasdf.c"
int main(void) {
 return sizeof(int);
}
 
Naja doch will ich schon:
Eine Struktur wird immer eingegeben, wenn der Nutzer eine weitere eingibt, wird Speicher für genau eine weitere Struktur reserviert.
Klar könnte ich das auch mit n*sizeof(str) machen, aber dann bräuchte ich noch eonen Zähler für die Anzahl der bisher eingegebenen Strukturen, den wollte ich mir sparen.
Oder geht es eben gar nicht ander?

LG
 
Egal, wie oft du realloc() aufrufst, der Speicher, den du bekommst hat immer die Größe 2 * sizeof(str)

€: Nach dem zweiten Aufruf von realloc() läuft der reservierte Speicher dann über, daher der Fehler.
Du bekommst 2 * sizeof(str) Bytes Speicher, aber willst eine dritte Struktur da rein schreiben. Das
schlägt dann natürlich fehl.

Du sagst selbst, dass du das nicht willst. Und wo ist das Problem, mitzuzählen, wie viel du brauchst?
 
Also kann man realloc nie in einer Schleife aufrufen, da es eh nur einmal anwendbar ist?
Habs grad mal mit nem Zähler gemacht, das ändert nix:

Code:
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <assert.h>

#define LEN 10

typedef struct{
	int i;
	char s[LEN];
}str;

void fkt(str *strptr){
	int ibuf;
	char sbuf[LEN];
	
	int rd, i = 0, n = 1;
	char ende = 'j';
	do{
		if(ende == 'n'){
			strptr = (str *)realloc(strptr, ++n * sizeof(str));
			assert(strptr != NULL);
			//hier lasse ich mir die Größe des reservierten Speichers anzeigen
			printf("DEBUG: size: %lu\n", sizeof(*strptr)/sizeof(str));
			i += 1;
		}
		
		do{
			char c;
			printf("Gib i und s ein.\n");
			rd = scanf("%d %s", &ibuf, (char*)sbuf);
			do{
				c = getchar();
			}while(c != '\n');
		}while(rd != 2);				
		strptr[i].i = ibuf;
		strncpy(strptr[i].s, sbuf, LEN);
		
		do{
			char c;
			printf("Ende? j/n\n");
			rd = scanf("%c", &ende);
			do{
				c = getchar();
			}while(c != '\n');
		}while(rd != 1);
	}while(ende == 'n');
}

void prs(str *strptr){
	int i;
	for(i = 0; i < (sizeof(*strptr)/sizeof(str)); i++){
		printf("Ausgabe: i = %d; s = \"%s\"\n", strptr[i].i, strptr[i].s);
	}
}

int main(void){
	str *sptr = malloc(sizeof(str));
	
	fkt(sptr);	
	prs(sptr);
	
	free(sptr);
	sptr = NULL;
	
	return 1;
}
 
Natürlich kann man das in einer Schleife aufrufen. Man muss ihm nur sagen, wie viel Speicher man benötigt. Und das hast du falsch gemacht.

€: strptr hat die Größe von str (da es vom selben Typ ist). Deshalb ergibt sizeof(*strptr)/sizeof(str) immer 1.
(falls dich das verwirrt hat).
 
Zuletzt bearbeitet:
Achso, jetzt versteh ich :D
Okay dann bleibt noch die Frage wieso beim dritten reallocieren der Fehler kommt?

EDIT: Okay der Fehler wurde wohl durch den Zähler behoben. Läuft jetzt alles bestens. Danke dir :)

LG
 
Zuletzt bearbeitet:
Zurück
Oben