42
Dynamischer Speicher und Struktur

Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

Embed Size (px)

Citation preview

Page 1: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

Dynamischer Speicher und

Struktur

Page 2: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

Beispiel:

Page 3: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender gibt die Anzahl der abzuspeichernden Räume ein. Die Länge, Breite und Höhe werden vorläufig (zu Testzwecken) durch das Programm festgelegt.

Page 4: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

Ein Raum wird durch folgende Struktur realisiert:

Page 5: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

struct dtraum{ int l; int b; int h;};

Page 6: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

Realisieren Sie das Programm durch ein Feld, dessen einzelne Elemente jeweils eine Struktur bilden.

Page 7: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

#include "stdafx.h"#include <malloc.h>

struct dtraum{int l;int b;int h;

};

// gleich geht es weiter...

Page 8: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

int main(){ int anz,i; struct dtraum v[1000];

printf("Anzahl eingeben =\n"); scanf("%d",&anz);

for(i=0;i<anz;i++){ v[i].l=i; v[i].b=i+10; v[i].h=i+20; }}

Welchen Nachteil hat dieses Programm bezüglich des Speicherplatzverbrauchs

Der Anwender kann mehr Speicher – als reserviert – verbrauchen.(z.B. bei Eingabe von 2000 für anz).

Dies ist dann “Unerlaubte Speicherbenutzung“Der Anwender kann weniger Speicher – als reserviert – verbrauchen

(z.B. bei Eingabe von 1 für anz).Dies ist dann “Speicherverschwendung“.

Um dies zu vermeiden kann der Anwender – während der Laufzeit des Programms – so viel Speicher reservieren, wie er benötigt.

Im Gegensatz zum Beispiel oben wird diese Reservierung nicht beim Compilieren, sondern während des Programmlaufs gemacht und heißt

deshalb dynamischer Speicher(reservierung).

Page 9: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

Die Funktion malloc kann während der Laufzeit des Programms eine gewünschte Menge Speicher (vom Betriebssystem) organisieren. Welche Angabe braucht man dann, um auf diesen Speicher zuzugreifen ?

Page 10: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

Man braucht die Anfangsadresse dieses reservierten Speicherbereichs.Die Funktion malloc liefert diese Anfangsadresse zurück.

Page 11: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

Beispiel:

Page 12: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

int main(){

int *pint;

pint = (int *) malloc(3*sizeof(int));

// pint = (int *) malloc(12);}

reserviert Speicher für 3 * Speicherbedarf(integer)

malloc verlangt, daß man - durch den cast Operator (..) - den Datentyp

angibt, auf den die Anfangsadresse des Speicherbereichs zeigt

nicht empfehlenswert: falls man weiß wieviel Speicher 3 Integer belegen, könnte man auch die Anzahl der Bytes direkt angeben

Anfangsadresse des reservierten Speichers

Page 13: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

Realisieren Sie das vorige Programm, in dem die Räume in einem Feld abgespeichert wurden, durch die Verwendung von dynamischem Speicher.

Page 14: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

#include "stdafx.h"#include <malloc.h>

struct dtraum{int l;int b;int h;

};

// gleich geht es weiter...

Page 15: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

int main(){ int i; int anz=0; struct dtraum *pr; printf("Anzahl eingeben\n\n"); scanf("%d",&anz); pr = (struct dtraum *) malloc (anz*sizeof(struct dtraum));

reserviert Speicher für...

Hier wird nachher der Anfang des dynamischen Speichers (in einem

Zeiger) festgehalten.

Welchen Wert hat pr an dieser Stelle ?

anz Speicherelemente mit dem Datentyp struct dtraum

0100 ?0100pr

berechnet den Speicherbedarf von der Struktur dtraum : 3 · Speicherbedarf(integer) = 12 Byte

Annahme:Die Variable pr werde an der Adresse 0100 gespeichert.

Page 16: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

... pr = (struct dtraum *) malloc (anz*sizeof(struct dtraum)); for(i=0;i<anz;i++){ (*(pr+i)).l=i;// (pr+i)->l=i;// pr[i].l=i; (pr+i)->b=i+10; (pr+i)->h=i+20; }

Annahme: anz = 2

0100 ?0100prgleiche Befehle, nur anders geschrieben

Page 17: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

... pr = (struct dtrau (anz*sizeof(st for(i=0;i<anz;i++) (*(pr+i)).l=i;// (pr+i)->l=i;// pr[i].l=i; (pr+i)->b=i+10; (pr+i)->h=i+20; }

??

0504... ?0508

?

0512

0516

05200100 05000100pr

Speicherreservierung für : 2 · sizeof(dtraum) = 2 · 3 · 4 Byte.

?...

...

...

??

????

... ?

0500...

Annahme: Speicherbereich beginnt bei Adresse 0500

Page 18: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

... pr = (struct dtraum (anz*sizeof(st for(i=0;i<anz;i++) (*(pr+i)).l=i;// (pr+i)->l=i;// pr[i].l=i; (pr+i)->b=i+10; (pr+i)->h=i+20; }

??

0504... ?0508

?

0512

0516

05200100 05000100pr

?...

...

...

??

????

... ?

0500...

*(0500 + 0 · 12)

Page 19: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

0504... ?0508

?

0512

0516

0520

?...

...

...

??

????

... ?

0500... 0 0 ...

pr = (struct dtraum (anz*sizeof(st for(i=0;i<anz;i++) (*(pr+i)).l=i;// (pr+i)->l=i;// pr[i].l=i; (pr+i)->b=i+10; (pr+i)->h=i+20; }

0100 05000100pr

*(0500 + 0 · 12)

Page 20: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

0504... ?0508

?

0512

0516

0520

?...

...

...

??

????

... ?

0500...

... pr = (struct dtraum (anz*sizeof(st for(i=0;i<anz;i++) (*(pr+i)).l=i;// (pr+i)->l=i;// pr[i].l=i; (pr+i)->b=i+10; (pr+i)->h=i+20; }

0100 05000100pr

0 0*(0500 + 0 · 12)

Page 21: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

0504...0508

0512

0516

0520

?...

...

...

??

????

... ?

0500... 0 0

1 0

... pr = (struct dtraum (anz*sizeof(st for(i=0;i<anz;i++) (*(pr+i)).l=i;// (pr+i)->l=i;// pr[i].l=i; (pr+i)->b=i+10; (pr+i)->h=i+20; }

0100 05000100pr

*(0500 + 0 · 12)

Page 22: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

0504...0508

0512

0516

0520

?...

...

...

??

????

... ?

0500... 0 0

1 0

... pr = (struct dtraum (anz*sizeof(st for(i=0;i<anz;i++) (*(pr+i)).l=i;// (pr+i)->l=i;// pr[i].l=i; (pr+i)->b=i+10; (pr+i)->h=i+20; }

0100 05000100pr

*(0500 + 0 · 12)

Page 23: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

0504...0508

0512

0516

0520

...

...

...

?????

... ?

0500... 0 0

1 0

2 0

... pr = (struct dtraum (anz*sizeof(st for(i=0;i<anz;i++) (*(pr+i)).l=i;// (pr+i)->l=i;// pr[i].l=i; (pr+i)->b=i+10; (pr+i)->h=i+20; }

0100 05000100pr

*(0500 + 0 · 12)

Page 24: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

0504...0508

0512

0516

0520

...

...

...

?????

... ?

0500... 0 0

1 0

2 0

... pr = (struct dtraum (anz*sizeof(st for(i=0;i<anz;i++) (*(pr+i)).l=i;// (pr+i)->l=i;// pr[i].l=i; (pr+i)->b=i+10; (pr+i)->h=i+20; }

0100 05000100pr

*(0500 + 1 · 12)

Page 25: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

0504...0508

0512

0516

0520

...

...

...???

... ?

0500... 0 0

1 0

2 0

0 1

... pr = (struct dtraum (anz*sizeof(st for(i=0;i<anz;i++) (*(pr+i)).l=i;// (pr+i)->l=i;// pr[i].l=i; (pr+i)->b=i+10; (pr+i)->h=i+20; }

0100 05000100pr

*(0500 + 1 · 12)

Page 26: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

0504...0508

0512

0516

0520

...

...

...???

... ?

0500... 0 0

1 0

2 0

0 1

... pr = (struct dtraum (anz*sizeof(st for(i=0;i<anz;i++) (*(pr+i)).l=i;// (pr+i)->l=i;// pr[i].l=i; (pr+i)->b=i+10; (pr+i)->h=i+20; }

0100 05000100pr

*(0500 + 1 · 12)

Page 27: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

0504...0508

0512

0516

0520

...

...

...?

... ?

0500... 0 0

1 0

2 0

0 1

1 1

... pr = (struct dtraum (anz*sizeof(st for(i=0;i<anz;i++) (*(pr+i)).l=i;// (pr+i)->l=i;// pr[i].l=i; (pr+i)->b=i+10; (pr+i)->h=i+20; }

0100 05000100pr

*(0500 + 1 · 12)

Page 28: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

0504...0508

0512

0516

0520

...

...

...?

... ?

0500... 0 0

1 0

2 0

0 1

1 1

... pr = (struct dtraum (anz*sizeof(st for(i=0;i<anz;i++) (*(pr+i)).l=i;// (pr+i)->l=i;// pr[i].l=i; (pr+i)->b=i+10; (pr+i)->h=i+20; }

0100 05000100pr

*(0500 + 1 · 12)

Page 29: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

0504...0508

0512

0516

0520

...

...

...

...

0500... 0 0

1 0

2 0

0 1

1 1

2 1

... pr = (struct dtraum (anz*sizeof(st for(i=0;i<anz;i++) (*(pr+i)).l=i;// (pr+i)->l=i;// pr[i].l=i; (pr+i)->b=i+10; (pr+i)->h=i+20; }

0100 05000100pr

*(0500 + 1 · 12)

Page 30: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

0504...0508

0512

0516

0520

...

...

...

...

0500... 0 0

1 0

2 0

0 1

1 1

2 1

... pr = (struct dtraum (anz*sizeof(st for(i=0;i<anz;i++) (*(pr+i)).l=i;// (pr+i)->l=i;// pr[i].l=i; (pr+i)->b=i+10; (pr+i)->h=i+20; }

0100 05000100pr

free(pr);

reservierten Speicher wieder freigeben

Page 31: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

WICHTIG:Die Verwendung von malloc sollte immer wie folgt geschehen:

Page 32: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

pr = (struct dtraum *) malloc (anz*sizeof(struct dtraum)); if(pr != NULL){ // z.B. Anweisungen // siehe oben... free(pr); }

Wenn pr den Wert NULL (0) hat bedeutet dies:Vom Betriebssystem kann kein Speicher mehr reserviert werden, weil z.B. schon vorher im Programm viel Speicher reserviert wurde.

Page 33: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

pr = (struct dtraum *) malloc (anz*sizeof(struct dtraum)); if(pr != NULL){ // Anweisungen // ... free(pr); }

pr->l=100;printf("%d", pr->l);

Was geschieht, wenn nach der Freigabe des reservierten Speichers auf diesen Speicher zugegriffen wird?

Es kann (muss aber nicht) zur Laufzeit eine Fehlermeldung erscheinen (übliche blaue Fenster...). Wenn keine Fehlermeldung erscheint, kann sich dieser Fehler später im Programm sehr unangenehm bemerkbar machen...

Page 34: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

Was macht das gleiche Programm, aber ohne die Anweisung:

pr = (struct dtraum *) malloc (anz*sizeof(struct dtraum));

Page 35: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

int main(){ int i; int anz=0; struct dtraum *pr; printf("Anzahl eingeben\n\n"); scanf("%d",&anz); for(i=0;i<anz;i++){ (*(pr+i)).l=i; (pr+i)->b=i+10; (pr+i)->h=i+20; }

0100 ?0100pr

Welchen Wert hat pr an dieser Stelle des Programms ?

? bedeutet:irgendein unbekannter, zufälliger Wert.Zum Beispiel: 0815

Page 36: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

int main(){ int i; int anz=0; struct dtraum *pr; printf("Anzahl eingeben\n\n"); scanf("%d",&anz); for(i=0;i<anz;i++){ (*(pr+i)).l=i; (pr+i)->b=i+10; (pr+i)->h=i+20; }

0100 08150100pr

Was steht an der Adresse 0815 im Arbeitsspeicher ?

Der Programmier weiß es nicht, denn er hat an dieser Adresse keinen Speicherplatz reservieren lassen und diesen entsprechend belegt.

Als schlimmer Fall könnte an der Adresse 0815 zum Beispiel...

ein Teil des Betriebssystems stehen!

Page 37: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

int main(){ int i; int anz=0; struct dtraum *pr; printf("Anzahl ein scanf("%d",&anz); for(i=0;i<anz;i++){ (*(pr+i)).l=i; (pr+i)->b=i+10; (pr+i)->h=i+20; }

0100 08150100pr

0815 Teildes

08170818 Syst.

0816Betr.

Page 38: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

int main(){ int i; int anz=0; struct dtraum *pr; printf("Anzahl ein scanf("%d",&anz); for(i=0;i<anz;i++){ (*(pr+i)).l=i; (pr+i)->b=i+10; (pr+i)->h=i+20; }

0100 08150100pr

0815

08170818

0816

Dieser Teil des Betriebssystems wird überschrieben

0 0 0 0

Page 39: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

Hier das ganze Programm...

Page 40: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

#include "stdafx.h"#include <malloc.h>

struct dtraum{int l;int b;int h;

};

int main(){ int i; int fehler=0; int anz=0; struct dtraum *pr;

printf("Bitte Anzahl der Raeume eingeben =\n"); scanf("%d",&anz); pr = (struct dtraum *) malloc (anz*sizeof(struct dtraum)); if(pr!=NULL){ for(i=0;i<anz;i++){ (pr+i)->l=i; (pr+i)->b=i+10; (pr+i)->h=i+20; } free(pr); }

Page 41: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

if(pr==NULL) printf("Es gibt keinen freien Speicher mehr");

// Nur zum Test: Zugriff auf freigegebenen Speicher pr->l=100; printf("%d", pr->l); return 0;}

Page 42: Dynamischer Speicher und Struktur. Beispiel: In einem Test-Programm werden die Anzahl, die Länge, Breite und Höhe mehrerer Räume gespeichert. Der Anwender

Übungsaufgaben:Siehe Aufgabenblatt