Frage zu realloc
-
Hi,
schau genau hin,
ich bin bei meiner vorigen Antwort fast drüber gefallen:
Meinst Du SIZE_GRID(I) oder SIZE_GRID(1) oder SIZE_GRID(l)?
Laß Dir beide Teile des Produkts vorher ausgeben!Könnte einen Unterschied machen ...
-
Es ist immer l wie Ludwig.
-
Hi skoll,
dann zerleg' mal Deinen Code ein bißchen:
Deintyp * temp = NULL; // SIZE_GRID(l) ausgeben // sizeof(PDT_GRID) ausgeben if (SIZE_GRID(l) && sizeof(PDT_GRID)) temp = realloc(FIRST_GRID_P(l),SIZE_GRID(l)*sizeof(PDT_GRID)); if (temp) FIRST_GRID_P(l) = temp; else free(FIRST_GRID_P(l)); // Fehlerbehandlung nicht vergessen!!
Damit ein bißchen klarer wird, ob die Größenberechnung schiefgeht oder die Speicheranforderung an und für sich. Hat zudem den Vorteil, daß beim Schiefgehen von realloc der Pointer nicht futsch ist ...
-
Habs ausprobiert. Es liegt nicht an SIZE_GRID(l) oder sizeof(PDT_GRID). Beide sind zur fraglichen Zeit groesser 0.
-
Dann ist der Block wohl doch zu groß, um geschlossen reserviert zu werden (das bedeutet nicht unbedingt, daß der Heap voll ist - eher daß er zu stark fragmentiert ist). Da wäre es eine gute Idee, gleich von Anfang an etwas mehr Speicher anzufordern als du gerade benötigst (und diesen Speicher auch in größeren Schritten zu vergrößern).
PS: Also daß sizeof() null liefern könnte, sollte eigentlich nicht passieren
(und wenn doch, dann fängt es nicht irgendwo im Programm damit an)
-
Ich habs auf verschiedenen Rechnern laufen lassen. Zwar alles HPs unter HPUX aber mit unterschiedlichem Memoryausbau. Auch habe ich verschiedene andere Programme parallel laufen lassen, um die Speichersituation zu variieren. Mein Programm bricht immer wieder an der selben Stelle ab. Ich denke schon, dass in meinem Programm ein Fehler steckt. Kann es sein, das ich zwischen zwei Aufrufen von:
FIRST_GRID_P(l)=realloc(FIRST_GRID_P(l),SIZE_GRID(l)*sizeof(PDT_GRID));
irgend etwas Verbotenes mit dem Speicher mache, auf den FIRST_GRID_P(l) zeigt? Wuerde realloc das merken und 0 liefern?
-
Hi skoll,
wenn's wirklich die Speicheranforderung ist, die bei theoretisch ausreichendem Speicher schiefgeht, die Multiplikanten plausibel usw., dann forschst Du an der falschen Stelle.
Vermutlich machst Du Dir irgendwo anders den Heap kaputt, z.B. durch ein free auf 'nen falschen Pointer ...
Da Du ein Array von Pointern hast, auch mal nachsehen, ob Du da immer sauber abräumst und immer den richtigen Index hast, bei Indexfehlern kann man sich oft blödsuchen.
Sorry, jetzt kann ich nur noch allgemeine Hinweise geben ...
-
Ich habe auch die Blockgroesse (BLOCKSIZE_GRID) variiert mit der ich die angeforderte Memorygrosse vergroessere.
fprintf(logfile,"\n\nDEBUG: alte groesse=%d\n",SIZE_GRID(l)*sizeof(PDT_GRID));
SIZE_GRID(l)+=BLOCKSIZE_GRID;
fprintf(logfile,"DEBUG: vorher=%d\n",FIRST_GRID_P(l));
fprintf(logfile,"DEBUG: neue groesse=%d\n",SIZE_GRID(l)*sizeof(PDT_GRID));FIRST_GRID_P(l)=realloc(FIRST_GRID_P(l),SIZE_GRID(l)*sizeof(PDT_GRID));
fprintf(logfile,"DEBUG: nachher=%d\n",FIRST_GRID_P(l));
Auch das hat leider nichts veraendert.
-
skoll1 schrieb:
Bei den Debugzeilen ist zu sehen, dass die neue Groesse mit 84000000 berechnet wird...
das sind ~80MB. soviel speicher könnte am stück nicht mehr frei sein.
-
skoll1 schrieb:
irgend etwas Verbotenes mit dem Speicher mache, auf den FIRST_GRID_P(l) zeigt? Wuerde realloc das merken und 0 liefern?
Kommt auf die Implementation von malloc() & Co an, aber wenn z.B. ein free() mit dem falschen Pointer erfolgt, hast Du Datensalat, bei dem realloc sehr wohl nur noch NULL- Pointer rückgeben kann.
-
Aber was macht denn realloc? Es versucht doch zunaechst freien Speicher zu bekommen. Wenn das klappt, kopiert es den angegebenen Speicher FIRST_GRID_P(l) da hin. realloc ist doch egal, was in diesem Speicher steht. Koennte FIRST_GRID_P(l) irgendwie "kaputt" gegangen sein. Die Adresse selbst, also worauf FIRST_GRID_P(l) zeigt ist ja noch unmittelbar vor dem realloc Aufruf o.k. wie die DEBUG-Zeilen zeigen. Die Adresse ist ja noch die gleiche, wie beim vorgerigen realloc Aufruf.
-
Was in deinen Daten drinsteht, ist realloc() tatsächlich egal. Aber um deine Daten herum hat der Heap-Manager noch eigene Hilfsdaten verteilt, wo z.B. drinsteht, wie groß der zugehörige Speicherblock ist - und die zu beschädigen könnte üble Folgen habem.
Und pale dog hat recht - 80MB am Stück anzufordern ist eine ganze Menge. Bei diesen Datenmengen solltest du anfangen, dir eine andere Datenstruktur zu überlegen.
-
Wie gesagt, das Programm bearbeitet weit groessere Modelle problemlos und das seit Jahren und auch bei vielen anderen Kollegen hier in der Firma. Der Arbeitsspeicher hier auf unseren Rechnern liegt so bei 2GB aufwaerts. Ich lese mit diesem Programm mehrere FEM-Modelle ein und verbinde sie zu einem. Komisch ist, das wenn ich die Reihenfolge der einzulesenden Modelle aendere, es kein Problem gibt, obwohl die Gesamtgroesse gleich bleibt.
-
Vielleicht hab' ich nur falsch geguckt:
Sag' mal, wie sind denn
FIRST_GRID_P(l) l
usw. typisiert?
-
Kann man sich die groesse des allocierten Memories ausgeben lassen? Also die groesse des allocierten Speichers auf den FIRST_GRID_P(l) zeigt? Dann koennte ich zwischen dem letzten und vorletzten realloc Aufrufen sehen, ob sich da was aendert.
-
skoll1 schrieb:
Kann man sich die groesse des allocierten Memories ausgeben lassen? Also die groesse des allocierten Speichers auf den FIRST_GRID_P(l) zeigt? Dann koennte ich zwischen dem letzten und vorletzten realloc Aufrufen sehen, ob sich da was aendert.
Das ist genau das, was Du angefordert hast, also das Produkt in Bytes.
Wenn's nicht klappt, kriegst Du NULL zurück.
Nachträglich kriegst Du aber nicht raus, wie groß der Mem- Block ist, auf den der Pointer zeigt.
-
Ja aber kann ich unmittelbar vor dem realloc Aufruf abfragen, ob sich die Groesse des Blocks auf den FIRST_GRID_P(l) zeigt seit dem letzten realloc Aufruf veraendert hat (ungewollter Weise).
-
Sorry, hatte die Antwort nicht genau gelesen. Nachtraeglich geht es also nicht mehr.
-
Mache fuer heute Feierabend. besten Dank soweit. Wenn jemandem noch was einfaellt, in welcher Richtung ich weiterforschen kann, waere ich sehr dankbar.
-
Habe den realloc Befehl mal ersetzt durch eine malloc/memcpy Kombination. Und siehe da, ihr hattet recht. Beim malloc gibts Probleme und nicht beim memcpy, d.h. das er tatsaechlich nicht genug zusammenhaengenden Speicher findet. Besten Dank.