[C] nochmal alloc/realloc

seraph

Grünschnabel
so also ich bin wohl einfach zu blöd :x

folgendes problem ... ich wollte um mir das mit malloc/realloc mal verständlich zu machn (da unser prof das irgendwie nicht verständlich erklären konnte) und es ja nun wirklich zu den grundlagen gehört eine stack simulation programmieren. ich hab sonst echt kein verständnisproblem beim programmieren aber hier bekomm ichs einfach ned hin. das ganze funktioniert bis auf das speicherproblem (da ich ja falls sich der user entscheidet ein weiteres element einzufügen, den bereitgestellten speicher um einen string vergrößern muss)

ich weiß das das echt ne nubie frage ist, aber man muss es eben erstmal EINMAL verstehen :/ hoffe ihr könnt mir helfen

ich poste jetzt eifnach mal den src den ich bis jetzt hab hier rein und hoffe auf eure verbesserungen (ist über verkettete listen gelöst wie ihr erkennen könnt ... ihc glaube ich brauch die ganzen listenfunktionen ned hier reinposten ;) (toll sowas versteh ich ohne probs und alloc ned *grml* :) naja helft mir mal auf die sprünge)
Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "list.h"

int main()
{
	tList *p_list;
	void *p_item;
	char input;
	int count = 0, result;
	char *item = (char *) malloc(sizeof(char *));

	p_list=CreateList();
	
	printf("\n\tKellerspeichersimulation\n\n\n");
	while (input != 'Q' && input != 'q')
	{
		printf("\nEnter (I)nsert / (O)ut / (Q)uit: ");
		fflush(stdin);
		input = getc(stdin);
		if (input == 'I' || input == 'i')
		{
			count++;
			printf("\neinzufuegende Zeichenkette: ");
			fflush(stdin);
			gets(item);
			item = (char *) realloc(item, count*sizeof(char *)+1);
			result = InsertHead(p_list, item);
			if (result == 1)
				printf("\nEinfuegen erfolgreich.");
				
			else
				printf("\nEinfuegen fehlgeschlagen.");
			
		}
		if (input == 'O' || input == 'o')
		{
			p_item = GetFirst(p_list);
			if (p_item == NULL)
				printf("\nKellerspeicher leer");
			else
			{
				printf("\noberste Zeichenkette: %s", p_item);
				RemoveItem(p_list);
				count--;
			}
		}
	}
	DeleteList(p_list);
	return 0;
}

ich weiß wenigstens warum es nicht funktioniert, aber eien lösung find ich deswegen trozdem nicht ... das problem ist wohl das es sich ja nicht um ein array mit strings handelt sondern nur um einen ... dieser wird dann verlängert, aber es kommt ja deswegen keine neue arrayzeile für nen neuen string dazu :/ ... vielleicht dnek ich auch falsch :x najut ... jetzt seit ihr dran

falls ihr wegen dem listenzeugs ned klarkommt dann nehmt einfach nen ähnliches beispiel ... (unbekannte anzahl an strings müssen abgespeichert werden) ... ich bekomm das dann schon abstrahiert :)

danke schonma für die die es gelesen haben sollte
 
Zuletzt bearbeitet:
Was willst du denn jetzt eigentlich wissen?

Ehrlich gesagt finde ich, dass du es uns ein bischen zu schwer machst. (Siehe durchgehende Kleinschreibung, klare Fragestellung, fehlende Sourceschnipsel usw. )
 
gut erklärt:
http://de.geocities.com/throni3/cpp/Kapitel_11.html
ist zwar für C++ aber die Grundlagen sind ja die selben.

stimmt es eigentlich das Speicher auf dem Heap der nicht wieder freigegeben wird erst nach einem Neustart wieder zu Verfügung steht ?
In allen anderen Büchern, Tutorials usw steht "nach Ende des Programms".
Ist das *betriebssystemspezifisch* ?
 
Zuletzt bearbeitet:
stimmt es eigentlich das Speicher auf dem Heap der nicht wieder freigegeben wird erst nach einem Neustart wieder zu Verfügung steht ?
In allen anderen Büchern, Tutorials usw steht "nach Ende des Programms".
Ist das *betriebssystemspezifisch* ?

das stimmt so halb ;-)

Also prinziell mal is es OS spezifisch, unter aktuellen system wird der speicher im sagen wir 90% der fälle automatisch frei gegeben.

Er wird es nicht wenn:
1.) Der speicher weder im Programm heap, noch im Programm stack reserviert wurde.
2.) Wenn der speicher auf einem Externen heap reserviert wurde.
3.) Der heap so schwer beschädigt ist, das er nicht zerstört werden kann.
4.) Das programm abnormal terminiert wird. (beispielweise 0xC0000005)

fall 1 tritt ein, wenn man mit systemhandle arbeitet. z.B. Device Contexte werden nicht automatisch gelöscht. Dateizugriffe. und so weiter.
also überall wo du mit HANDLE arbeitest, und dadurch systemspeicher allozierst der nicht auf dem heap landet, musst du ihn mit CloseHandle() frei geben. sonst memleak.

fall 2 tritt auf wenn man mit CreateHeap arbeitet, und selbst Heaps erzeugt, diese heaps werden nicht automatisch gelöscht.

fall 3 tritt nur bei extrem schweren pointerfehlern auf, in der regel stürzt das programm ab bevor es so weit kommt. ansonsten bedankt sich windows mit einem Bluescreen

fall 4 sollte eigendlich nur während des debuggingsauftreten, tut es leider aber bei vielen programmen auch so... :(
 
Danke ersteinmal an alle die sich die Zeit genommen haben mein Zeug zu lesen. Es tut mir erst einmal leid, dass ich es euch "so schwer gemacht habe". Ich werde mich veruschen zu bessern :D. Gut nun noch einmal zu meinem Problem. Ich erkläre es jetzt einfach mal ohen den Sourcecode, weil es sonst einfach zu umständlich für euch wird.

Stellt euch vor ich schreibe ein Programm und weiß noch nicht, wieviele Strings denn nun in ein Array müssen. Ich fange also erst einmal an das Array für einen string zu definieren. Dann später im Programm stelle ich fest (durch eine Nutzereingabe zum Beispiel), dass ich ja doch noch einen String mehr in das Array bringen muss (und das unter umständen beliebig oft).

Das das ganze letztlich über eine zweifache Indizierung bzgw. Doppelpointer funktioniert, hatte ich heute morgen noch slbst herrausgefunden, dennoch danke für dein Tutorial.

Ich werde das jetzt erstmal versuchen selbst mit dem Doppelpointer hinzubekommen, denke das sollte ich noch schaffen. Wenn ich eine Lösung gefunden habe, schreibe ich noch einmal hier rein.

Nochmal ein großes sorry an alle Diejenigen, die mit meinem Post Schwierigkeiten hatten :-/
 
so geschafft und gecheckt

So also ich habe jetzt eine Lösung gefunden (jhat auch nur 10 mins gedauert), auch Dank dem von Euch zur Verfügung gestellten Tutorial. Auch wenn es da um C++ ging hab ichs doch irgendwie abstrahiert bekommen und für alle Diejenigen, die nochmal auf dieses Problem stoßen sollten und mit der Suchen-Funktion hier landen, hier jetzt mal meine Lösung, ganz aus dem Kontext gerissen:

Code:
char **items = (char **) malloc(sizeof(char **));
items[0] = (char *) malloc(sizeof(char *));

/* Speicherreservierung für einen String */
...
...
/* man bermerkt, dass man doch n Strings braucht */

items = realloc(items, 7*sizeof(char *));
for (i=4; i<7; i++)
	items[i] = (char *) malloc(sizeof(char *));

/* in diesem Bsp: 4 bisherige Größe (Zeilenanzahl) des Arrays, also 
von 0-3. Die 7 steht in diesem Falle dann für "bis wohin" (n), also nach der 
Allocierung sind die Arrayzeilen 0-6 verfügbar, wobei die alten 
Inhalte in 0-3 bestehen bleiben. */
...
...
/* am Ende natürlich den Speicher wieder freigeben */

free(items);

So, dass wars erstmal von mir. Falls ihr meine Lösung für nicht gut oder so haltet, immer laut schreien ;D Ansonsten noch einmal danke an Alle, die hier geantwortet haben.
 
Zuletzt bearbeitet:
Sieht doch gut aus.

Die doppelten * sind allerdings einer der Gründe, warum ich froh bin in C++ so fortschrittliche Konstrukte wie std::list und std::string verwenden zu können... :)
 
Zurück