c und malloc

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
penthesilea
Beiträge: 147
Registriert: 19.02.2003 23:51:24
Wohnort: Ulm

c und malloc

Beitrag von penthesilea » 20.05.2003 01:42:36

Hallo

ich hätt' da mal ne frage. Nämlich ich soll als Übung ne Aufgabe in C programmieren und ich habe das noch nie getan.

Also es geht darum. Ich soll unter Linux mit Hilfe des gcc ein C- Programm schreiben, welches einen Speicherblock von 4 Byte mit malloc alloziert. Und mit einer Zeigeroperation und einer Schleife soll ich schauen, wieviel Byte Speicher ich jetzt tatsächlich bekommen habe.

Hier mein Code:

Code: Alles auswählen

 #include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main (void) {
	int *bla;
	int *test;
	int i;
	int mem=0;

                     bla =(int *)malloc(4);
	
	for(i=0; i <1000000000; i++) {
	                     test = bla+i;
		*test = 1;
		mem = mem +4;
		printf("bytes bis putt: %d\n", mem);
	}
	return 0;
}
so und nu meine Idee.
also Mittels malloc alloziere ich nu die 4 Byte.
Die for- Schleife lass ich jetzt halt bis zu dieser willkürlichen Zahl laufen. Denn ich habe mir gedacht, dass ich sicher irgendwann mal nicht mehr in den speicher schreiben darf. Und dann das Programm abstürzt. ja und bei meinem versuch dies zu machen kamen 2288 Bytes raus. die bekomm ich durch den Zähler mem und dadurch dass integer 4 Byte gross ist, zähl ich bei jedem Durchlauf um 4 hoch.

Nun meine Frage: sehe ich das richtig dass ich 2288 Bytes alloziert bekommen habe oder ist das nur Zufall, und das ich in Wirklichkeit 4 Byte bekommen habe und der restliche Speicher zufällig frei ist?

oh je

Gruss penthesilea

Benutzeravatar
riankrimsteel
Beiträge: 131
Registriert: 23.03.2003 19:06:06
Wohnort: Göttingen
Kontaktdaten:

Beitrag von riankrimsteel » 20.05.2003 08:28:39

Hi,

das dein Programm nach n Bytes abstürzt ist völlig zufällig. Malloc reserviert genau die Grösse Speicher die verlangt hast. Wenn du über diesen Speicher hinausschreibst, passiert solange nichts, bis du auf einen Speicherbereich triffst, der schon von einem anderem Prozess benutzt wird.
Btw wenn Malloc keinen Speicher reservieren kann liefert es einen NULL-Zeiger zurück.

Gruss
Dennis

PS: die string.h wird von deinem Programm nicht gebraucht.
PPS: wofür ist das "*test = 1"?
For every problem, there is a solution that's simple, easy, and wrong.

Benutzeravatar
Bert
Beiträge: 3751
Registriert: 16.07.2002 14:06:52
Wohnort: Dresden
Kontaktdaten:

Beitrag von Bert » 20.05.2003 10:31:30

mir ist die Aufgabenstellung recht unlar. Was soll das bringen? malloc() und Konsorten allocieren Speicher der geforderten Größe. Entweder das klappt, oder das klappt nicht; dann ist der Rückgabewert == 0 ; Mir ist keine Funktion bekannt, mit der man die reale Größe der angeforderten Speichers errechenen kann ( ich wußte auch gar nicht,das da ein Unterschied sein kann, hab gerade gelesen, das durch Alignment mehr Speicher ausgefaßt werden kann). Das ist in der Regel doch aber irrelevant.

@riankrimsteel: Mit dem *test = 1 wird versucht, auf den Speicher zu schreiben, um zu sehen, ob das noch gültig ist...

PS: Du hast da noch einen Denkfehler drin, durch den cast auf int* tust Du nicht bytes Zählen, sondern sizeof(int).
Programmer: A biological machine designed to convert caffeine into code.
xmpp:bert@debianforum.de

Benutzeravatar
penthesilea
Beiträge: 147
Registriert: 19.02.2003 23:51:24
Wohnort: Ulm

Beitrag von penthesilea » 20.05.2003 12:07:30

Hallo

noch ein bisschen was zu Erklärung.

Ich soll das für die Vorlesung Betriebssysteme programmieren. Es ist das erste Übungsblatt und dem Prof ist klar, dass es viele in der Vorlesung gibt, die noch nie C prgrammiert haben. Er meinte, das würde ein 5 Zeiler und sowieso recht einfach und es müsste jeder dieser Aufgabe hinbekommen.

Und das Thema zu diesem Übungsblatt ist die Speicherverwaltung (interne, externe Fragmentierung, wie kann man Speicherzuordnen.....).

@Bert: ein int ist doch ein Byte gross und deswegen Zähle ich doch dann die Bytes, aber halt nur vierer Blöcke und zählen tu ich ja einfach nur mit der Variable mem und die Zähl ich hoch, bis das Programm abstürzt.

Gruss penthesilea

PS: ich habe noch nie c Programmiert

Benutzeravatar
Bert
Beiträge: 3751
Registriert: 16.07.2002 14:06:52
Wohnort: Dresden
Kontaktdaten:

Beitrag von Bert » 20.05.2003 13:01:38

nein, ein int ist bei den meisten Compilern nicht 1 Byte groß (oder bei allen? da der Zahlenbereich > 255 ist) Mach einfach mal ein sizeof(int) und lass Dir das Ergebniss ausgeben.
Was Du willst ist ein char.

Noch eine Idee: Angenommen malloc() bekommt hintereinander liegende Speicherbereiche, dan könnte so was hier gehen:

Code: Alles auswählen

// test2.cpp : Definiert den Einsprungpunkt für die Konsolenanwendung.
//


#include <string>
#include <iostream>


int main(int argc, char* argv[])
{
	int	size;

	size = sizeof(int);

	std::cout << "Size of Type int: " << size << std::endl;

	//test malloc()
	char	*p1;
	char	*p2;
	p1 = (char*)malloc(4);
	p2 = (char*)malloc(4);
	// jetzt sollte man p1 und p2 auf <> 0 testen

	std::cout << "Abstand zwische denPointern:" << p2 - p1 << std::endl;
	
	free(p1);
	free(p2);
	return 0;
}

Das hat hier bei mir mit VisualC++ unter Win2k eine Size von 4 und einen Abstand von 65 ergeben.

Das mit dem Abstand ist aber so eine Sache, da der Speicher fragmentiert sein kann..
Programmer: A biological machine designed to convert caffeine into code.
xmpp:bert@debianforum.de

Benutzeravatar
pdreker
Beiträge: 8298
Registriert: 29.07.2002 21:53:30
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Nürnberg

Beitrag von pdreker » 21.05.2003 02:37:37

Uiuiuiuiui..... 8O

Der tiefere Sinn dieser Aufgabe erschliesst sich mir zwar auch nach mehrfachem Lesen nicht, aber was soll's...

malloc() ist deutlich komplizierter als nur das allokieren von Speicher. malloc() ist eine libc Funktion hinter der ein riesiger Apparat steckt, der dafür sorgt, dass Fragmentierung gehandhabt wird, und dass alles auf die Hardware passt. So wird malloc z.B. auf Intel Architekturen hinter den Kulissen immer 4k Blöcke allokieren, weil das die feinste Einteilung ist die das virtuelle Speichermanagement auf diesen CPUs kann.

Die 2288 Bytes kommen (ungefähr) folgendermassen zustande:
Wenn Dein Programm geladen wird belegt das System gerade soviele 4k Blöcke, wie der Programmcode benötigt. Wenn Dein binary also 1000 Bytes hat, wird das Programm trotzdem 4k (also 4096 Bytes) zur Verfügung haben. Wenn Du jetzt das malloc() machst schaut die Libc, ob sie nicht evtl. schon genug Speicher hat, und einfach gar nix machen muss, ausser Dir den Zeiger zurückzugeben und sich das zu merken. Es wird also im Prinzip gar kein neuer Speicher belegt, sondern der bereits belegte erstmal ausgenutzt. Die 4 Bytes, die Du allokieren willst passen also noch gut in die 4k die schon reserviert sind. Also gibt malloc Dir einfach einen Pointer zurück, der hinter Deinem Programmcode liegt (plus lokale Vars usw.). Wenn Du jetzt mit der Schleife hochzählst und in den Speicher schreibst gibt es erst dann einen SegFault, wenn Du aus den 4k herausläufst, was in Deinem Fall halt nach 2288 Bytes der Fall ist... Zu diesem Zeitpunkt hast Du aber wahrschenlich schon einiges an internen Datenstrukturen (Stack) deines eigenen Programms überschrieben...

@bert:
Der Abstand zwischen den Pointern erklärt sich dadurch, dass malloc immer auch ein paar Verwaltungsdaten mit in dem Speicher ablegt, und daher natürlich in Wirklichkeit etwas mehr Speicher allokiert, als man angefordert hat. Mit diesen Daten macht malloc dann die Buchführung und z.B. free() nutzt diese Informationenl um zu wissen, wieviele Bytes es an der angegeben Adresse freigeben kann. (free() nimmt nur eine Adresse als Parameter...)

Jetzt, wo ich das geschrieben habe, fällt mir was auf... Genau das könnte das Lernziel der Übung sein: realisieren, dass das Speichermanagement hinter den Kulissen anders funktioniert, als es den Anschein hat. Wenn man x Bytes allokiert kann man durchaus mehr Speicher haben, weil es halt im OS anders funktioniert...

Hth
Patrick
Definitely not a bot...
Jabber: pdreker@debianforum.de

Benutzeravatar
penthesilea
Beiträge: 147
Registriert: 19.02.2003 23:51:24
Wohnort: Ulm

Beitrag von penthesilea » 21.05.2003 12:04:14

Hallo
Jetzt, wo ich das geschrieben habe, fällt mir was auf... Genau das könnte das Lernziel der Übung sein: realisieren, dass das Speichermanagement hinter den Kulissen anders funktioniert, als es den Anschein hat. Wenn man x Bytes allokiert kann man durchaus mehr Speicher haben, weil es halt im OS anders funktioniert...
und genau das ist es auch, hab ne Mail an den Prof geschrieben und so wie ich die aufgabe im 1. Post gelöst habe, ist richtig. Er wollte das genauso, hat aber leider als er die aufgabe gemacht hat, übersehen, dass man nalt nicht herausfinden kann, ob der Bereich nach malloc zufällig frei ist oder ob es der zugeordnete ist.

Euch allen vielen Dank

Gruss penthesilea

PS: volle Punktzahl bekommen habe

Antworten