[C: MSVC++] Virtueller Speicher geht in die Knie

mc_gulasch

Erfahrenes Mitglied
Morgen zusammen,

ich hab ein Programm zur Stringtransformation geschrieben und wollte es gerade mit einer entspannten Menge von 180k Strings durchgesten, doch leider geht mein Virtueller Speicher zwischen 3k und 10k in die Knie. Leider hab ich keine Ahnung warum. Ihr Erfahreneren könnt mir doch sicher ein paar Hinweise auf dei "Klassiker" geben, oder?
Was ich u.a. mache ist, dass ich jedesmal wenn ein String reinkommt, zwei Tabellen allozieren muss,
C:
strings_in = (int**) calloc(256,sizeof(int*)); //wird freigegeben
	for (i=0;i<256;i++)
		strings_in[i] = (int*) calloc(256,sizeof(int));
	
	strings_out = (int**) calloc(256,sizeof(int*)); //wird freigegeben
	for (i=0;i<256;i++)
		strings_out[i] = (int*) calloc(256,sizeof(int));
die ich aber nach Verwendung sofort wieder freigebe.

Danke für JEDE Idee.

Gulasch
 
Hi.
mc_gulasch hat gesagt.:
C:
strings_in = (int**) calloc(256,sizeof(int*)); //wird freigegeben
	for (i=0;i<256;i++)
		strings_in[i] = (int*) calloc(256,sizeof(int));
Solange du die Unterobjekte auch freigibst sollte hier kein Speicher verloren gehen.

Du könntest ein Speicherleck-Detektions-Programm verwenden. Falls du VC++ 5, 6 oder 7 verwendest könntest du z.B. http://www.codework.com/glowcode/features.html ausprobieren. Hab aber keine Ahnung wie gut das ist, aber es gibt sicher noch andere Programme.

Gruß
 
Hi

mach mal vieleicht gibts ja ne spezielle stelle

if((strings_in = (int**) calloc(256,sizeof(int*))) == NULL){
fprintf(stderr," %i ",i);
perror("Fehler ");
return 0;
}

mach mal bei beiden.

mfg mike4004
 
deepthroat hat gesagt.:
Solange du die Unterobjekte auch freigibst sollte hier kein Speicher verloren gehen
Die Unterobjekte waren´s. Allerdings tritt jetz ein neues Problem auf und zwar folgendes:
Ich setze zwei globale Variablen
C:
int **modell;
int **testmodells;
Diese werden mit den folgenden Methoden allokiert und wieder freigegeben:
C:
void alloc_tabs(void)
{
	int i = 0;
	modell = (int**) calloc(256,sizeof(int*)); 
	for (i=0;i<256;i++)
		modell[i] = (int*) calloc(256,sizeof(int));
	
	testmodells = (int**) calloc(256,sizeof(int*)); 
	for (i=0;i<256;i++)
		testmodells[i] = (int*) calloc(256,sizeof(int));
}
void dealloc_tabs(void)  
{
	int i = 0;
	for (i=0;i<256;i++)
	{
		free(modell[i]);
		free(testmodells[i]);
	}
	free(modell);
	free(testmodells);
}
Jetzt hab ich eine Funktion
C:
int** search_string(char *string)
{
...
 string_search(bla,blub,modell) //hierbei wird in modell das ergebnis geschrieben
 return testmodells; //nicht schön, da global, aber von vorher halt noch nicht verändert
}

int main (void)
{
 ...
 while (!feof(input))
 {
  alloc_tabs();                    //<---- HIER
  string = fgets(input);
  ergebnis = search_string(string);
  dealloc_tabs();
 }
 ...
 return 0;
}

Im Endeffekt machen diese Funktionen genau das gleiche, wie zuvor. Das einzige, was ich umgestellt habe, war die Globalisierung von "modell" und "testmodells", sowie die ständige Allokierung und Freigabe über eigene Funktionen. Allerdings ist jetzt mein "modell" leer im zweiten Schritt (also beim ersten search_string packt er es, aber im zweiten hab ich nen Speicherfehler. Es hängt definitiv nicht von den eingegebenen Strings ab, da es IMMER ne Lösung gibt. Ich hab auch getestet: string_1 geht, string_2 nicht => vertauschen string_2 geht, string_1 nicht).
Es muss irgendwie mit meiner Speicherverwaltung zu tun haben, aber ich blick da nimmer durch :(
Any Ideas? Wäre super


//edit: Hab die Allokierung auch in die main-Funktion gepackt. Jetzt geht zwar die Zuweisung in "modell" , allerdings krieg ich einen Assertion - Failure mit der Meldung:
Code:
Debug Assertion Failed
Program: *meins*
File: dbgheap.c
Line: 1044

Expression: _CrtIsValidHeapPointer(pUserData)
Naja, sagt mir herzlich wenig, aber ich werd mal weitersuchen und hier immerwieder mal reinblinzeln, ob wer ne Idee hat.
 
Zuletzt bearbeitet:
Wie sieht denn deine string_search Funktion aus?

Du darfst den Wert von den Variablen modell und testmodell natürlich nicht ändern. Sonst kannst du die ja nicht mehr freigeben.

Gruß
 
deepthroat hat gesagt.:
Du darfst den Wert von den Variablen modell und testmodell natürlich nicht ändern
Ist mir nicht klar. Ich dachte ich allokier nur den Speicher in der main - Fkt, also halte ihn frei.
deepthroat hat gesagt.:
Wie sieht denn deine string_search Funktion aus?
Zu groß für hier, egal, alles was wichtig ist:
Die string_search sucht über strings zugehörige Daten (eine Art Hash), so dass dann diese Daten in "modell" zwischengespeichert werden um dann alle gefunden Ergebnisse in "testmodells" zu speichern.
Wenn ich jetzt die Werte von "testmodells" und "modell" in der string_search nicht ändern darf, hab ich ein Problem, weil:
- In der string_search könnt ich sie zwar allokieren, aber nicht freigeben
- In der main kann ich sie allokieren und freigeben, aber nicht verändern
:confused: Was mach ich denn jetzt da? Oder hab ich dich jetzt falsch verstanden?


//EDIT2:

So, soweit so gut. Gelöst ist aber leider noch nicht wirklich etwas. Ich hab jetzt folgendes Konstrukt
C:
int **modell_1
char **modell_2

void funktion(void)
{
 int modell_size = *bestimmterWert*;
 modell_1 = (int**) calloc(modell_size,sizeof(int*));						    
	for (i=0;i<modell_size;i++) 
		modell_1[i] = (int*) calloc((256),sizeof(int));
 modell_2 = (char**) calloc(modell_size,sizeof(char*));
	for (i=0;i<modell_size;i++) 
		modell_2[i] = (char*) calloc((100),sizeof(char));
 ....
}

int main(void)
{
  ...
  return 0;
}

Was mich hierbei stört, ist die Tatsache, dass ich modell_1 und modell_2 bis zum schluss der main - Funktion brauchen werde, aber keine Möglichkeit hab, sie wieder freizugeben. Wahrscheinlich stellt´s jedem vernünftigen Programmierer bei meiner "globalen" Variablendefinition die Haare auf. Zurecht ;)

Hat jemand spontan ne Idee, wie man so ein Problem lösen könnte?

Danke vom Gulasch.
 
Zuletzt bearbeitet:
Ich meinte du darfst da nicht sowas machen wie
C:
*modell++ = ...;
denn das verändert ja den Wert der Variablen. Du kannst selbstverständlich den Wert auf den der Zeiger zeigt verändern - schließlich hast du ja Speicher dafür allokiert.

Teste mal ruhig wie mike4004 schon vergeschlagen hat immer ob die Allokation erfolgreich war.

Die Ausnahme CrtIsValidHeapPointer(pUserData) bedeutet das du irgendeiner Funktion keinen gültigen Zeiger übergeben hast für den du gar keinen Speicher allokiert hast.

Gruß
 
Aaaaalles klar. Kapiert. Der Fehler hat sich behoben und was das etwas schwierige an der Sache war, dass ein
C:
fclose(file);
gefehlt hat und es dadurch den Speicher schmeisst.
Das von mike4004 hab ich ausprobiert und hat mir im Einzelfall nie Fehler geschmissen, aber natürlich der Schleife und dem ganz "Drumeherum" schon.

Vielen herzlichen Dank, ihr habt mir echt weitergeholfen.
 
Zurück