
Captulo 31 - alocao dinmica de memria

NEW - este procedimento permite a alocao de uma rea de memria de tama-
nho correspondente ao da varivel associada ao ponteiro passado como argu-
mento. Caso no tenhamos espao suficiente no HEAP de memria, haver a ocor-
rncia de um erro de execuo. A varivel do tipo ponteiro passada como pa-
rmetro, passa a conter o endereo da rea de memria que passa a ocupar.
Este tipo de varivel fica conhecido, como varivel dinmica, no podendo
este procedimento ser usado em conjunto com MARK e RELEASE. Sua sintaxe:
NEW (VAR <p> : POINTER);
Vejamos um exemplo:
PROGRAM teste_new;
USES CRT;
TYPE
  ptr = registro;
  registro = RECORD
    nome : STRING[30];
    ende : STRING[25];
    prox : ptr;
  END;
VAR
  reg : registro;
  pprimeiro,
  ltimo : PTR;
  ind : BYTE;
BEGIN
  CLRSCR;
  GOTOXY (15,1);
  WRITE (alocao dinmica de memri);
  primeiro := NIL;
  ltimo := NIL
  FOR ind := 1 TO 10 DO
    BEGIN
      NEW (p);
      GOTOXY (1,ind + 5);
      WRITE (entre com o , ind, nome: );
      READLN (p.nome);
      GOTOXY (40,ind + 5);
      WRITE (e com o , ind, endereo :);
      READLN (p.ende);
      p.prox := NIL;
      IF primeiro = NIL
        THEN
          primeiro := p;
      IF ltimo = NIL
        THEN
          ltimo := p
      ELSE
        BEGIN
          ltim.prox := p;
          ltimo := p;
        END;
    END;
  ind := 1;
  CLRSCR;
  WHILE primeiro <> NIL DO
    BEGIN
      WRITELN (, ind, registr, primeir.nome, , primeir.ende);
      primeiro := primeir.prox;
      ind := ind + 1;
    END;
  REPEAT
  UNTIL READKEY <> #0;
END.

DISPOSE - este procedimento permite que se libere a memria alocada previa-
mente pelo procedimento NEW e aps a execuo deste procedimento, o contedo
do ponteiro  destrudo e qualquer referncia a ele causar um erro de execu-
o no programa, assim tambm como se for pedido para que se libere uma 
rea de memria que estiver fora da regio do HEAP. Este procedimento nunca
poder ser usado em conjunto com MARK e RELEASE. Sua sintaxe:
DISPOSE (VAR <p> : POINTER);
Vejamos um exemplo:
PROGRAM teste_dispose;
USES CRT;
TYPE
  ptr = registro;
  registro = RECORD
    nome : STRING[30];
    ende : STRING[25];
    prox : ptr;
  END;
VAR
  reg : registro;
  p, primeiro,
  ltimo : ptr;
  ind : BYTE;
BEGIN
  CLRSCR;
  GOTOXY (15,1);
  WRITE (alocao dinmica de memri);
  primeiro := NIL;
  ltimo := NIL;
  FOR ind := 1 TO 10 DO
    BEGIN
      NEW (p);
      GOTOXY (1,ind + 5);
      WRITE (entre com ,ind, nome: );
      READLN (p.nome);
      GOTOXY (40,ind + 5);
      WRITE (e com o , ind, endereo: );
      READLN (p.ende);
      p.prox := NIL;
      IF primeiro = NIL
        THEN
          primeiro := p;
      IF ltimo = NIL
        THEN
          ltimo := p
      ELSE
        BEGIN
          ltim.prox := p;
          ltimo := p;
        END;
    END;
  ind := 1;
  CLRSCR;
  WHILE primeiro <> NIL DO
    BEGIN
      WRITELN (,ind,registr,primeir.nome, ,primeir.ende);
      DISPOSE (primeiro);
      primeiro := primeir.prox;
    ind := ind + 1;
  END;
  REPEAT
  UNTIL READKEY <> #0;
END.

MARK - este procedimento permite que uma varivel do tipo ponteiro fique 
com o valor do HEAP, o qual por sua vez,  todo o espao de memria dispo-
nvel, que ficar alocado at que use o comando RELEASE. Sua sintaxe:
MARK (VAR <p> : POINTER);

RELEASE - este procedimento permite liberar toda a memria alocada pelo 
comando MARK. Tanto o comando MARK quanto o comando RELEASE, no podem ser 
utilizados em conjunto com os comandos DIPOSE e FREEMEN. No caso de utilizar-
mos o comando RELEASE, todos os processos de alocao de memria dinmica,
tais como NEW ou GETMEM, utilizados aps o uso do comando MARK sero libera-
dos. Sua sintaxe:
RELEASE (VAR <p> : POINTER);
Vejamos um exemplo sobre os dois ltimos comandos:
PROGRAM teste_mark_release;
USES CRT;
TYPE
  ptr = registro;
  registro = RECORD
    nome : STRING[30];
    ende : STRING[25];
    prox : ptr;
  END;
VAR
  reg : registro;
  heap : POINTER;
  p,primeiro,
  ltimo : ptr;
  ind : BYTE;
BEGIN
  CLRSCR;
  GOTOXY (15,1);
  WRITE (alocao dinmica de memri);
  primeiro := NIL;
  ltimo := NIL
  MARK (heap);
  FOR ind := 1 TO 10 DO
    BEGIN
      NEW (p);
      GOTOXY (1, ind + 5);
      WRITE (entre com o , ind, nome :);
      READLN (p.nome);
      GOTOXY (40,ind + 5);
      WRITE (e com o , ind,endereo: );
      READLN (P.ende);
      p.prox := NIL;
      IF primeiro = NIL
        THEN
          primeiro := p;
      IF ltimo := NIL
        THEN
          ltimo := p;
      ELSE
        BEGIN
          ltim.prox := p;
          ltimo := p;
        END;
    END;
  ind := 1;
  CLRSCR;
  WHILE primeiro <> NIL DO
    BEGIN
      WRITELN (, ind, registr,primeir.nome, , primeir.ende);
      primeiro := primeir.prox;
      ind := ind + 1;
    END;
  RELEASE (heap);
  REPEAT
  UNTIL READKEY <> #0;
END.

GETMEM - este procedimento cria uma nova varivel dinmica com o tamanho 
especificado no parmetro, e coloca o endereo de memria em uma varivel
do tipo ponteiro. Caso no haja espao suficiente para a alocao em me-
mria, ocorrer um erro de execuo. O bloco definido como tamanho no pode
ultrapassar o tamanho do Heap - 15 Bytes, ou seja, 65521. Sua sintaxe:
GETMEM (VAR <P> : POINTER, <tamanho> : WORD);

FREEMEM - este procedimento permite que se libere uma rea de memria de 
acordo com um tamanho passado como parmetro. Ele destri toda a referncia
associada  memria liberada e no pode ser utilizado com MARK ou RELEASE.
Sua sintaxe:
FREEMEM (VAR <p> : POINTER, <tamanho> : WORD);
Exemplo:
PROGRAM teste_getmem_freemem;
USES CRT;
TYPE
  ptr = registro;
  registro = RECORD
    nome : STRING[30];
    ende : STRING[25];
   prox : ptr;
  END;
VAR
  reg : registro;
  p,primeiro,
  ltimo : ptr;
  ind : BYTE;
BEGIN
  CLRSCR;
  GOTOXY (15,1);
  WRITE (alocao dinmica de memri);
  primeiro := NIL;
  ltimo := NIL;
  FOR ind := 1 TO 10 DO
    BEGIN
      GETMEM (p,SIZEOF (reg));
      GOTOXY (1,ind + 5);
      WRITE (entre com , ind,nome: );
      READLN (p.nome);
      GOTOXY (40<ind + 5);
      WRITE (e com o , ind,endereo: );
      READLN (p.ende);
      p.prox := NIL;
      IF primeiro = NIL
      THEN
        primeiro := p;
    IF ltimo = NIL
      THEN
       ltimo := p
    ELSE
      BEGIN
        ltim.prox := p;
        ltimo := p;
      END;
    END;
  ind := 1;
  CLRSCR;
  WHILE primeiro <> NIL DO
    BEGIN
      WRITELN (, ind, registr,primeir.nome, , primeir.ende);
      FREEMEM (primeiro, SIZEOF (reg));
      primeiro := primeir.prox;
      ind := ind + 1;
    END;
  REPEAT
  UNTIL READKEY <> #0;
END.  

MAXAVAIL - esta funo retorna o valor do maior bloco contnuo do Heap, 
correspondente  maior varivel dinmica que pode ser utilizada em um
programa. Sua sintaxe:
MAXAVAIL : LONGINT;

MEMAVAIL - esta funo retorna o valor de toda a memria disponvel, ou 
seja, todo o somatrio dos blocos livres existentes. Sua sintaxe:
MEMAVAIL : LONGINT;
PROGRAM teste_maxavail_memavail;
USES CRT;
TYPE
  ptr = registro;
    registro = RECORD
    nome : STRING[30];
    ende : STRING[25];
    prox : ptr;
  END;  
VAR
  reg : registro;
  p : ptr;
BEGIN
  CLRSCR;
  GOTOXY (15,1);
  WRITE (alocao dinmica de memri);
  GOTOXY (15,12);
  WRITE (o maior espao contnuo disponvel, na memria  , MAXAVAIL);
  GOTOXY (15,15);
  WRITE (o espao de memria total  ,MEMAVAIL);
  REPEAT
  UNTIL READKEY <> #0;
END.
