Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Dynamischer Speicher und Struktur

Ähnliche Präsentationen


Präsentation zum Thema: "Dynamischer Speicher und Struktur"—  Präsentation transkript:

1 Dynamischer Speicher und Struktur

2 Beispiel:

3 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.

4 Ein Raum wird durch folgende Struktur realisiert:

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

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

7 #include "stdafx.h" #include <malloc.h> struct dtraum{ int l; int b; int h; }; // gleich geht es weiter...

8 printf("Anzahl eingeben =\n"); scanf("%d",&anz);
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).

9 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 ?

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

11 Beispiel:

12 int main(){ int. pint; pint = (int. ) malloc(3
int main(){ int *pint; pint = (int *) malloc(3*sizeof(int)); // pint = (int *) malloc(12); } malloc verlangt, daß man - durch den cast Operator (..) - den Datentyp angibt, auf den die Anfangsadresse des Speicherbereichs zeigt reserviert Speicher für 3 * Speicherbedarf(integer) nicht empfehlenswert: falls man weiß wieviel Speicher 3 Integer belegen, könnte man auch die Anzahl der Bytes direkt angeben Anfangsadresse des reservierten Speichers

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

14 #include "stdafx.h" #include <malloc.h> struct dtraum{ int l; int b; int h; }; // gleich geht es weiter...

15 printf("Anzahl eingeben\n\n"); scanf("%d",&anz);
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)); Hier wird nachher der Anfang des dynamischen Speichers (in einem Zeiger) festgehalten. reserviert Speicher für... Welchen Wert hat pr an dieser Stelle ? berechnet den Speicherbedarf von der Struktur dtraum : 3 · Speicherbedarf(integer) = 12 Byte pr 0100 0100 ? Annahme: Die Variable pr werde an der Adresse 0100 gespeichert. anz Speicherelemente mit dem Datentyp struct dtraum

16 gleiche Befehle, nur anders geschrieben
... 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 pr 0100 0100 ? gleiche Befehle, nur anders geschrieben

17 ... 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; } 0500 ? ... ? 0504 ? ... ? 0508 ? ... ? 0512 ? ... ? Annahme: Speicherbereich beginnt bei Adresse 0500 0516 ? ... pr 0100 0100 0500 ? 0520 ? Speicherreservierung für : 2 · sizeof(dtraum) = 2 · 3 · 4 Byte. ... ?

18 ... 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; } *( · 12) 0500 ? ... ? 0504 ? ... ? 0508 ? ... ? 0512 ? ... ? 0516 ? ... pr 0100 0100 0500 ? 0520 ? ... ?

19 ... 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; } *( · 12) 0500 0 0 ... 0504 ? ... ? 0508 ? ... ? 0512 ? ... ? 0516 ? ... pr 0100 0100 0500 ? 0520 ? ... ?

20 ... 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; } *( · 12) 0500 0 0 ... 0504 ? ... ? 0508 ? ... ? 0512 ? ... ? 0516 ? ... pr 0100 0100 0500 ? 0520 ? ... ?

21 ... 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; } *( · 12) 0500 0 0 ... 0504 1 0 ... 0508 ? ... ? 0512 ? ... ? 0516 ? ... pr 0100 0100 0500 ? 0520 ? ... ?

22 ... 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; } *( · 12) 0500 0 0 ... 0504 1 0 ... 0508 ? ... ? 0512 ? ... ? 0516 ? ... pr 0100 0100 0500 ? 0520 ? ... ?

23 ... 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; } *( · 12) 0500 0 0 ... 0504 1 0 ... 0508 2 0 ... 0512 ? ... ? 0516 ? ... pr 0100 0100 0500 ? 0520 ? ... ?

24 ... 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; } *( · 12) 0500 0 0 ... 0504 1 0 ... 0508 2 0 ... 0512 ? ... ? 0516 ? ... pr 0100 0100 0500 ? 0520 ? ... ?

25 ... 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; } *( · 12) 0500 0 0 ... 0504 1 0 ... 0508 2 0 ... 0512 0 1 ... 0516 ? ... pr 0100 0100 0500 ? 0520 ? ... ?

26 ... 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; } *( · 12) 0500 0 0 ... 0504 1 0 ... 0508 2 0 ... 0512 0 1 ... 0516 ? ... pr 0100 0100 0500 ? 0520 ? ... ?

27 ... 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; } *( · 12) 0500 0 0 ... 0504 1 0 ... 0508 2 0 ... 0512 0 1 ... 0516 1 1 ... pr 0100 0100 0500 0520 ? ... ?

28 ... 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; } *( · 12) 0500 0 0 ... 0504 1 0 ... 0508 2 0 ... 0512 0 1 ... 0516 1 1 ... pr 0100 0100 0500 0520 ? ... ?

29 ... 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; } *( · 12) 0500 0 0 ... 0504 1 0 ... 0508 2 0 ... 0512 0 1 ... 0516 1 1 ... pr 0100 0100 0500 0520 2 1 ...

30 reservierten Speicher wieder freigeben
... 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; } reservierten Speicher wieder freigeben 0500 0 0 ... 0504 1 0 ... 0508 2 0 ... 0512 0 1 ... 0516 1 1 ... pr 0100 0100 0500 0520 2 1 ... free(pr);

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

32 // z.B. Anweisungen // siehe oben... free(pr); } if(pr != NULL){
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.

33 if(pr != NULL){ // Anweisungen // ... free(pr); } pr->l=100;
pr = (struct dtraum *) malloc (anz*sizeof(struct dtraum)); if(pr != NULL){ // Anweisungen // ... free(pr); } Was geschieht, wenn nach der Freigabe des reservierten Speichers auf diesen Speicher zugegriffen wird? pr->l=100; printf("%d", pr->l); 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...

34 Was macht das gleiche Programm, aber ohne die Anweisung: pr = (struct dtraum *) malloc (anz*sizeof(struct dtraum));

35 printf("Anzahl eingeben\n\n"); scanf("%d",&anz);
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; } Welchen Wert hat pr an dieser Stelle des Programms ? ? bedeutet: irgendein unbekannter, zufälliger Wert. Zum Beispiel: 0815 pr 0100 0100 ?

36 printf("Anzahl eingeben\n\n"); scanf("%d",&anz);
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; } 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! pr 0100 0100 0815

37 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; } 0815 Teil 0816 des 0817 Betr. 0818 Syst. pr 0100 0100 0815

38 for(i=0;i<anz;i++){ (*(pr+i)).l=i; (pr+i)->b=i+10;
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; } 0815 0816 0817 0818 Dieser Teil des Betriebssystems wird überschrieben pr 0100 0100 0815

39 Hier das ganze Programm...

40 #include "stdafx. h" #include <malloc. h> struct dtraum{. int l;
#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); }

41 if(pr==NULL) printf("Es gibt keinen freien Speicher mehr");
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; }

42 Übungsaufgaben: Siehe Aufgabenblatt


Herunterladen ppt "Dynamischer Speicher und Struktur"

Ähnliche Präsentationen


Google-Anzeigen