Mudanças entre as edições de "AULA 20 - Programação 1 - Engenharia"
Linha 68: | Linha 68: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
+ | <blockquote style="background: lime; border: 1px solid black; padding: 1em;"> Observe o uso do operador sizeof para captura do tamanho do inteiro. Esta abordagem garante portabilidade. </blockquote> | ||
===Alocando uma estrutura === | ===Alocando uma estrutura === |
Edição das 08h53min de 7 de junho de 2018
ALOCAÇÃO DINÂMICA DE MEMóRIA
Objetivos
- apresentar a anatomia de um programa em execução;
- apresentar a alocação dinâmica de memória.
A área de heap e o layout de memória de um programa C
Neste link podemos ter uma ideia da anatomia de um programa na memória do computador.
http://shivacherukuri.blogspot.com.br/2011/03/memory-layout-in-cdata-segmentbss-code.html
Podemos observar que existe as seguintes áreas:
- TEXT: área onde está o código;
- BSS: dados estaticamente alocados e não inicializados;
- DATA: dados estaticamente alocados e inicializados;
- STACK: área de pilha (variáveis locais);
- HEAP: área de dados alocados dinamicamente.
Quando declaramos uma variável global da forma:
int x;
a variável x é alocada em uma área chamada BSS (dados não inicializados). Note que x possui uma área de memória reservada a ela (4 bytes) e cuja existência é o tempo de vida do programa em execução. Esta aŕea de BSS é zerada no início do programa de forma que todas as variáveis ali definidas começarão com o valor 0.
Da mesma forma, uma variável global da forma:
int y=10;
é alocada na área de DATA. A inicialização é definida normalmente na carga do programa. Os valores de inicialização são copiados para a área de DATA na carga do programa, a partir do arquivo executável.
Por vezes, o tamanho dos dados não são conhecidos antes da execução do programa. Neste caso, pode ser interessante criá-los dinamicamente e é neste ponto que entra a área de HEAP. Trata-se de uma área de memória, gerenciada a partir de funções da biblioteca do C.
As funções mais conhecidas são (http://en.wikipedia.org/wiki/C_dynamic_memory_allocation):
http://www.linuxjournal.com/article/4681 http://www.cs.cmu.edu/~guna/15-123S11/Lectures/Lecture08.pdf
Exemplo 1: Alocação dinâmica de números inteiros (exercício puramente didático):
#include <stdlib.h>
main()
{
int *px, *py; /*variáveis ponteiros para inteiro criadas no STACK */
int resultado; /* variável reasultado criada no STACK */
px = (int *) malloc(sizeof(int)); /* alocada área para um inteiro na área de HEAP */
/* ponteiro aponta para esta área */
*px = 5; /* colocado 5 na área apontada por px */
py = (int *) malloc(sizeof(int)); /* similara anterior para ponteiro py */
*py = 2;
resultado = *px + *py; /* soma os dois valores inteiros que estava na área de HEAP
e coloca o valor na variável resultado */
free (px); /* libera a área no HEAP que estava apontada por px */
px = NULL; /* zero o ponteiro para deixá-lo apontando para área indevida */
free (py);
py = NULL;
}
Observe o uso do operador sizeof para captura do tamanho do inteiro. Esta abordagem garante portabilidade.
Alocando uma estrutura
#include <stdio.h>
#include <stdlib.h>
void main()
{
struct TTeste{
int x;
int y;
};
struct TTeste *teste;
teste = (struct TTeste *) malloc (sizeof(struct TTeste));
if (teste==NULL) {
printf("erro de alocação");
exit(1);
}
teste->x=10;
free(teste);
teste=NULL;
Usando o typedef para ajudar na definição e declaração de estruturas
#include <stdio.h>
#include <stdlib.h>
void main()
{
typedef struct {
int x;
int y;
} TTeste;
TTeste *teste;
teste = (TTeste *) malloc (sizeof(TTeste));
if (teste==NULL) {
printf("erro de alocação");
exit(1);
}
teste->x=10;
free(teste);
teste=NULL;
}
Alocando dinamicamente uma tabela de estruturas
#include <stdio.h>
#include <stdlib.h>
void main()
{
struct TTeste{
int x;
int y;
} *teste;
if ((teste = (struct TTeste *) malloc (100*sizeof(struct TTeste)))==NULL) {
printf("erro de alocação");
exit(1);
}
teste[10].x= 5;
if ((teste = realloc(teste, 10000*sizeof(struct TTeste)))==NULL) {
printf("erro de alocação");
exit(1);
}
teste[9000].x=20;
free(teste);
}
Exercício:
Refazer o exemplo anterior para que a quantidade de memória a ser alocada pela tabela seja passada na linha de comando.