Thema indholdsfortegnelse -- Tastaturgenvej: 'u'  Forrige tema i denne lektion -- Tastaturgenvej: 'p'  Næste slide i denne lektion -- Tastaturgenvej: 'n'Pointers og Arrays
26.  Statisk og dynamisk lagerallokering

Variable kræver lagerplads når programmet kører. Vi siger, at der allokeres lager til vore vore variable. Når vi i kildeprogrammet har erklæret en variabel vil køretidssystemet klare lagerallokeringen af variablen uden yderligere programøranstrengelser. Dette er statisk lagerallokering.

I C er det også muligt, når programmet kører, at bede om lager, som ikke er indeholdt i nogen variable. Når dette sker vil vi få overdraget en pointer til begyndelsen af det pågældende lagerområde. Dette kaldes dynamisk lagerallokering.

26.1 Statisk lagerallokering26.3 Dynamisk lagerallokering (2)
26.2 Dynamisk lagerallokering (1)
 

26.1.  Statisk lagerallokering
Indhold   Op Forrige Næste   Slide Aggregerede slides    Stikord Programindeks Opgaveindeks 

I kurset indtil nu har vi benyttet statisk lagerallokering for alle data

Med statisk lagerallokering afsættes lagerplads implicit når den omkringliggende blok aktiveres. Lagerplads inddrages implicit når blokken forlades.

I programmet herunder allokeres tab1 og tab2 statisk i main. Til tab1 afsættes plads til N doubles. N er en symbolsk konstant, som er defineret til 500. Til tab2 afsættes plads til N*K doubles, altså konkret 500 doubles (eller typisk 4000 bytes). Der allokeres naturligvis også lager til i.

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
#define N  500
#define K   10

int main(void) {
  int i;
  double tab1[N];       /* allocation of N doubles */
  double tab2[N*K];     /* allocation of N*K doubles */

  /* do something with tab1 and tab2 */
  return 0;
}
Program 26.1    Illustration af statisk lagerallokering i C.

Når main er kørt færdig frigives lagerpladsen, som er afsat til tab1, tab2 og i.

Statisk lagerallokering er knyttet til erklæringen af variable.

Udtryk som indgår i indeksgrænser for et array skal være statiske udtryk

 

26.2.  Dynamisk lagerallokering (1)
Indhold   Op Forrige Næste   Slide Aggregerede slides    Stikord Programindeks Opgaveindeks 

I mange tilfælde ved vi først på programmets køretid hvor meget lager vi har brug for. Dette kan f.eks. afhænge af et tal, som er indlæst tidligere i programkørslen. Derfor er dynamisk lagerallokering ikke let at komme uden om.

Der er ofte behov for en mere fleksibel og dynamisk form for lagerallokering, hvor det kørende program eksplicit allokerer lager.

Med dynamisk lagerallokering afsættes lagerplads eksplicit, når programmet har behov for det.

I program 26.2 vises et forsøg på at at allokere passende plads til a i forhold til n, som er et indlæst heltal.

Ideen med at indlæse n i en ydre blok i forhold til den blok, hvor arrayet allokeres er god. Men vi skal ikke regne med, at den virker i C. ANSI C kræver, at n er et konstant udtryk, hvilket vil sige at der kun må indgå konstanter i udtrykket. sizeof operatoren kan også indgå.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>

int main(void) {

  int n;
  printf("Enter an integer size:\n");
  scanf("%d",&n);

  { int i;
    double a[n];

    for (i = 1; i < n; i++) 
      a[i] = (double)i;

    for (i = 1; i < n; i++) 
      printf("%f ", a[i]);
    printf("\n");

  }
  
  return 0;
}
Program 26.2    Et kreativt forsøg på dynamisk allokering - ikke ANSI C.

I stedet for at bruge ideen i program 26.2 skal vi anvende enten malloc eller calloc, som eksemplificeret i program 26.3. På det røde sted allokerer vi plads til n heltal (ints). Vi får en pointer til lagerområdet. Læg mærke til at a er en pointer til en int. Det nyallokerede lagerområde bruges i de to efterfølgende forløkker. På det blå sted deallokerer vi igen lagerområdet. Det betyder at vi overgiver lageret til C køretidssystemet, som så efterfølgende kan bruge det til andre formål. F.eks. kan lageret genbruges hvis vi lidt efter igen beder om nyt lager via calloc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
   int   *a, i, n, sum = 0;

   printf("\n%s",
      "An array will be created dynamically.\n\n"
      "Input an array size n followed by n integers:  ");
   scanf("%d", &n);
   a = calloc(n, sizeof(int));  /* get space for n ints */
   for (i = 0; i < n; ++i)
      scanf("%d", &a[i]);
   for (i = 0; i < n; ++i)
      sum += a[i];
   free(a);                     /* free the space */
   printf("\n%s%7d\n%s%7d\n\n",
      " Number of elements:", n,
      "Sum of the elements:", sum);
   return 0;
}
Program 26.3    Et program der foretager dynamisk allokering af et array.

Vi viser afslutningsvis et program, som dynamisk allokerer plads til det array, som vi illustrerede i figur 25.1. Allokeringen sker på det røde sted. I dette eksempel frigiver vi ikke lagerpladsen, idet lageret bruges helt til programafslutningen.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <stdlib.h>

#define N 2
#define M 3

int main(void) {
  int *pint, i, j;

  pint = malloc(N*M*sizeof(int));

  for (i=0; i<N; i++)
   for (j=0; j<M; j++)
     *(pint + M*i + j) = (i+1) * (j+1);

  for (i = 0; i < M * N; i++){
    printf("%4i ", *(pint + i));
    if ((i+1) % M == 0) printf("\n");
  }

  return 0;
}
Program 26.4    Et program der dynamisk allokerer et to-dimensionelt array.

 

26.3.  Dynamisk lagerallokering (2)
Indhold   Op Forrige Næste   Slide Aggregerede slides    Stikord Programindeks Opgaveindeks 

Herunder opsummerer vi dynamisk lagerallokering.

  • Dynamisk lagerallokering

    • Eksplicit allokering med calloc eller malloc fra fra stdlib.h

      • calloc(n, m): Allokerer et nulstillet array med n elementer på hver m bytes.

      • malloc(n): Allokerer n bytes, som ikke nulstilles.

    • Eksplicit deallokering med funktionen free

    • Risiko for dangling references

      • Hvis en pointer til et dynamisk allokeret objekt følges efter at objektet er deallokeret med free

I mange moderne sprog styres lager deallokering af en garbage collector, som frigiver lagerplads, når det ikke længere kan tilgås af programmet.

Understøttelse af lageradministration med en garbage collector er et meget spændende emne. En diskussion af dette falder dog uden for rammerne af disse noter.

Genereret: Onsdag 7. Juli 2010, 15:11:53
Thema indholdsfortegnelse -- Tastaturgenvej: 'u'  Forrige tema i denne lektion -- Tastaturgenvej: 'p'  Næste slide i denne lektion -- Tastaturgenvej: 'n'