![Page 1: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/1.jpg)
Estruturas de DadosAulas 3 e 4: Uso da memória e Vetores
09/04/2014
![Page 2: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/2.jpg)
Uso da memória
• Existem 3 maneiras de reservar o espaço da memória:– Variáveis globais (estáticas)
• Espaço existe enquanto programa estiver executando
– Variáveis locais• Espaço existe enquanto a função que declarou estiver
executando
– Espaços dinâmicos (alocação dinâmica)• Espaço existe até ser explicitamente liberado
![Page 3: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/3.jpg)
Alocação estática da memória (2)
• int v[1000]– Espaço contíguo na memória para 1000 valores
inteiros– Se cada int ocupa 4 bytes, 4000 bytes, ~4KB
• char v[50]– Espaço contíguo na memória para 50 valores do
tipo char– Se cada char ocupa 1 byte, 50 bytes
![Page 4: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/4.jpg)
Alocação estática X Alocação dinâmica
• Exemplo: Alocar nome e sobrenome dos alunos do curso– 3000 espaços de memória– Vetor de string (alocação estática)– 100 caracteres (Tamanho máximo do nome
inteiro)– Podemos então definir 30 pessoas – Não é o ideal pois a maioria dos nomes não usam
os 100 caracteres– Na alocação dinâmica não é necessário definir de
ante-mão o tamanho máximo para os nomes.
![Page 5: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/5.jpg)
Alocação dinâmica da memória
• Oposto a alocação estática• Técnica que aloca a memória sob demanda• Os endereços podem ser alocados, liberados e
realocados para diferentes propósitos, durante a execução do programa
• Em C usamos malloc(n) para alocar um bloco de memória de tamanho n bytes.
• Responsabilidade do programador de liberar a memória após seu uso
void *malloc(size_t size); // size_t == unsigned int
![Page 6: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/6.jpg)
Alocação dinâmica da memória (2)
• Espaço endereçável (3000) ainda livre:
– Alocar espaço para o nome PEDRO– 5 bytes para o nome e um byte para o caractere
NULL (\0). Total 6 bytes• Malloc (6)
![Page 7: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/7.jpg)
Alocação dinâmica da memória (3)
– Escrevemos PEDRO no espaço
– Alocamos e escrevemos PATRICIA
P E D R O \0
P E D R O \0
P A T R I C I A \0
![Page 8: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/8.jpg)
Alocação dinâmica da memória (4)
• Endereços não necessariamente contíguos• Alocador de memória do SO aloca blocos de
memória que estão livres• Alocador de memória gerencia espaços
ocupados e livres• Memória alocada contém lixo. Temos que
inicializar• Em C, liberamos a memória usando free(p)void free(void *ptr);
P A T R I C I A \0
![Page 9: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/9.jpg)
Alocação dinâmica da memória (5)
• Alocação e liberação rígida. Exemplo#define FREE(p) if(p!=NULL){free(p);p=NULL;}
...
int n, *v = NULL;
...
n = ...
v = (int*)malloc(n);
...
FREE(v);
...
FREE(v); // redundante, mas sem problema
![Page 10: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/10.jpg)
Alocação dinâmica (problemas)
• Liberar memória é responsabilidade do usuário – Evitar invasão de memória estranha ao processo
em execução (“memory violation”)– acesso errado à memória, usada para outro
propósito
• Fragmentação– Blocos livres de memória não contíguos
• Estruturas encadeadas fazem melhor uso da memória fragmentada
![Page 11: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/11.jpg)
Endereçamento em alocação dinâmica
• Precisamos saber os endereços dos espaços de memória usados
• Ponteiros são variáveis que armazenam o endereço na própria memóriachar *p; char *q;
P E D R O \0 P A T R I C I A \0
1 9
P A T R I C I A \0P E D R O \0 1 9
p q
1 9
![Page 12: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/12.jpg)
Alocação dinâmica em C
• Funções disponíveis na stdlib – malloc
• void *malloc (size_t num); // size_t == unsigned int• Allocar n bytes e retornar ponteiro para a memória
– calloc• void *calloc (size_t num, size_t size);• Ponteiro para (num*size) bytes
– realloc• void *realloc (void *ptr, size_t num);• Mudar tamanho da memória alocada
– free• void free (void *p);
![Page 13: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/13.jpg)
malloc#include <stdio.h>#include <stdlib.h>
int main (int argc, char** argv){int *p=NULL;int a;... /* Determina o valor de a em algum lugar */p=(int *)malloc(a*sizeof(int));if (!p) // equivalente: p==NULL{ printf ("** Erro: Memoria Insuficiente **\n");
exit(EXIT_FAILURE);}...if(p!=NULL) {free(p);p=NULL;}
return EXIT_SUCCESS;}
Alocada memória suficiente para se colocar a números inteiros
![Page 14: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/14.jpg)
calloc#include <stdio.h>#include <stdlib.h>#define FREE(ptr) if(ptr!=NULL){free(ptr);ptr=NULL;}
int main (int argc, char** argv){int *p=NULL;int a;...p=(int *)calloc(a, sizeof(int));
if (!p) // equivalente: p==NULL{ printf ("** Erro: Memoria Insuficiente **\n"); exit(EXIT_FAILURE);}...if(p!=NULL) {free(p);p=NULL;}return EXIT_SUCCESS;
}
Alocada memória suficiente para se colocar a números inteiros
![Page 15: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/15.jpg)
free
#include <stdio.h>#include <stdlib.h>int main (int argc, char** argv){int *p=NULL;int a;... /* Determina o valor de a em algum lugar */p=(int *)malloc(a*sizeof(int));if (!p) // equivalente: p==NULL{ printf ("** Erro: Memoria Insuficiente **\n"); exit(EXIT_FAILURE);}...if(p!=NULL) {free(p);p=NULL;}return EXIT_SUCCESS;}
![Page 16: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/16.jpg)
Alocação Dinâmica
• Motivação– Alocação fixa de memória (em tempo de
desenvolvimento do programa) pode ser ineficiente– Por exemplo, alocar tamanhos fixos para nomes de
pessoas pode inutilizar memória visto que existem tamanhos variados de nomes
– Com alocação fixa em memória podemos ter espaços alocados na memória que não são utilizados
• Solução: Alocação Dinâmica– é um meio pelo qual o programa pode obter memória
enquanto está em execução.– Obs.: tempo de desenvolvimento versus tempo de
execução
![Page 17: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/17.jpg)
Alocação da Memória
• Constantes: codificadas dentro do código objeto em tempo de compilação
• Variáveis globais (estáticas): alocadas no início da execução do programa
• Variáveis locais (funções ou métodos): alocadas através da requisição do espaço da pilha (stack)
• Variáveis dinâmicas: alocadas através de requisição do espaço do heap.– O heap é a região da memória entre o programa
(permanente) e a stack– Tamanho do heap é a princípio desconhecido do
programa
![Page 18: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/18.jpg)
Memória
aabb
aabb
10010101...10010101...10010101...10010101...
““constante”constante”““constante”constante”
Sist.OperacionalSist.OperacionalSist.OperacionalSist.Operacional
HeapPointerInício da ÁreaAlocável
StackPointerInício da Pilha
Topo da Memória
Base da Memória
Variáveis estáticas
Código objeto
Constantes
Direção de crescimento
Programa executável
![Page 19: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/19.jpg)
• Programa:
#include <stdio.h>char *a, *b;
int func_A (){ int local1, local2;
- - - }void func_B (){
int localA, localB;localA = func_A();localB = func_A();
}main (...){
a = "Essa aula é legal";b = "Será mesmo?"func_B();
}
aabb
aabb
10010101...10010101...10010101...10010101...
"Essa aula é ..."Essa aula é ..."Será mesmo.."Será mesmo..
"Essa aula é ..."Essa aula é ..."Será mesmo.."Será mesmo..
Sist.OperacionalSist.OperacionalSist.OperacionalSist.Operacional
HeapPointerInício da ÁreaAlocável
StackPointerInicio da Pilha
Topo da Memória
Base da Memória
Variáveis estáticas
Código objeto
Constantes
![Page 20: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/20.jpg)
• ProgramaPrograma::
#include <stdio.h>#include <stdio.h>
char *a, *b;char *a, *b;
int func_A ()int func_A ()
{{
int local1, local2;int local1, local2;
- - - - - -
}}
void func_B ()void func_B ()
{ {
int localA, localB;int localA, localB;
localA = func_A();localA = func_A();
localB = func_A();localB = func_A();
}}
main (...)main (...)
{{
a = "Essa aula é legal";a = "Essa aula é legal";
b = "Será mesmo?";b = "Será mesmo?";
func_B();func_B();
}}
aabb
aabb
10010101...10010101...
"Essa aula é ..."Essa aula é ..."Será mesmo.."Será mesmo..
"Essa aula é ..."Essa aula é ..."Será mesmo.."Será mesmo..
Sist.OperacionalSist.Operacional
HeapPointerInício da ÁreaAlocável
StackPointerInicio da Pilha
Topo da Memória
Base da Memória
Variáveis estáticas
Código objeto
Constantes
![Page 21: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/21.jpg)
• Programa:Programa:#include <stdio.h>#include <stdio.h>
char *a, *b;char *a, *b;
int func_A ()int func_A ()
{{
int local1, local2;int local1, local2;
- - - - - -
}}
void func_B ()void func_B ()
{ {
int localA, localB;int localA, localB;
localA = func_A();localA = func_A();
localB = func_A();localB = func_A();
}}
main (...)main (...)
{{
a = "Essa aula é legal";a = "Essa aula é legal";
b = "Será mesmo?"b = "Será mesmo?"
func_B();func_B();
}}
Sist.OperacionalSist.Operacional
"Essa aula é ..."Essa aula é ..."Será mesmo.."Será mesmo..
10010101...10010101...
aabb
HeapPointerTopo da ÁreaAlocável
StackPointerTopo da Pilha
Topo da Memória
Base da Memória
Variáveis estáticas
Código objeto
Constantes
![Page 22: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/22.jpg)
Programa:Programa:
#include <stdio.h>#include <stdio.h>
char *a, *b;char *a, *b;
int func_A ()int func_A ()
{{
int local1, local2;int local1, local2;
- - - - - -
}}
void func_B ()void func_B ()
{ {
int localA, localB;int localA, localB;
localA = func_A();localA = func_A();
localB = func_A();localB = func_A();
}}
main (...)main (...)
{{
a = "Essa aula é legal";a = "Essa aula é legal";
b = "Será mesmo?"b = "Será mesmo?"
func_B();func_B();
}}
Sist.OperacionalSist.Operacional
"Essa aula é ..."Essa aula é ..."Será mesmo.."Será mesmo..
10010101...10010101...
aabb
HeapPointerTopo da ÁreaAlocável
StackPointerTopo da Pilha
Topo da Memória
Base da Memória
Variáveis estáticas
Código objeto
Constantes
&main-#3localAlocalB
![Page 23: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/23.jpg)
Programa:Programa:
#include <stdio.h>#include <stdio.h>
char *a, *b;char *a, *b;
int func_A ()int func_A ()
{{
int local1, local2;int local1, local2;
- - - - - -
}}
void func_B ()void func_B ()
{ {
int localA, localB;int localA, localB;
localA = func_A();localA = func_A();
localB = func_A();localB = func_A();
}}
main (...)main (...)
{{
a = "Essa aula é legal";a = "Essa aula é legal";
b = "Será mesmo?"b = "Será mesmo?"
func_B();func_B();
}}
Sist.OperacionalSist.Operacional
"Essa aula é ..."Essa aula é ..."Será mesmo.."Será mesmo..
10010101...10010101...
aabb
HeapPointerTopo da ÁreaAlocável
StackPointerTopo da Pilha
Topo da Memória
Base da Memória
Variáveis estáticas
Código objeto
Constantes
&main-#3localAlocalB
![Page 24: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/24.jpg)
Programa:Programa:
#include <stdio.h>#include <stdio.h>
char *a, *b;char *a, *b;
int func_A ()int func_A ()
{{
int local1, local2;int local1, local2;
- - - - - -
}}
void func_B ()void func_B ()
{ {
int localA, localB;int localA, localB;
localA = func_A();localA = func_A();
localB = func_A();localB = func_A();
}}
main (...)main (...)
{{
a = "Essa aula é legal";a = "Essa aula é legal";
b = "Será mesmo?"b = "Será mesmo?"
func_B();func_B();
}}
Sist.OperacionalSist.Operacional
"Essa aula é ..."Essa aula é ..."Será mesmo.."Será mesmo..
10010101...10010101...
aabb
HeapPointerTopo da ÁreaAlocável
StackPointerTopo da Pilha
Topo da Memória
Base da Memória
Variáveis estáticas
Código objeto
Constantes
&main-#3&main-#3localAlocalAlocalBlocalB
&func_B-#2&func_B-#2local1local1local2local2
![Page 25: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/25.jpg)
Programa:Programa:
#include <stdio.h>#include <stdio.h>
char *a, *b;char *a, *b;
int func_A ()int func_A ()
{{
int local1, local2;int local1, local2;
- - - - - -
}}
void func_B ()void func_B ()
{ {
int localA, localB;int localA, localB;
localA = func_A();localA = func_A();
localB = func_A();localB = func_A();
}}
main (...)main (...)
{{
a = "Essa aula é legal";a = "Essa aula é legal";
b = "Será mesmo?"b = "Será mesmo?"
func_B();func_B();
}}
Sist.OperacionalSist.Operacional
"Essa aula é ..."Essa aula é ..."Será mesmo.."Será mesmo..
10010101...10010101...
aabb
HeapPointerTopo da ÁreaAlocável
StackPointerTopo da Pilha
Topo da Memória
Base da Memória
Variáveis estáticas
Código objeto
Constantes
&main-#3&main-#3localAlocalAlocalBlocalB
&func_B-#2&func_B-#2local1local1local2local2
![Page 26: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/26.jpg)
Programa:Programa:
#include <stdio.h>#include <stdio.h>
char *a, *b;char *a, *b;
int func_A ()int func_A ()
{{
int local1, local2;int local1, local2;
- - - - - -
}}
void func_B ()void func_B ()
{ {
int localA, localB;int localA, localB;
localA = func_A();localA = func_A();
localB = func_A();localB = func_A();
}}
main (...)main (...)
{{
a = "Essa aula é legal";a = "Essa aula é legal";
b = "Será mesmo?"b = "Será mesmo?"
func_B();func_B();
}}
Sist.OperacionalSist.Operacional
"Essa aula é ..."Essa aula é ..."Será mesmo.."Será mesmo..
10010101...10010101...
aabb
HeapPointerTopo da ÁreaAlocável
StackPointerTopo da Pilha
Topo da Memória
Base da Memória
Variáveis estáticas
Código objeto
Constantes
&main-#3localAlocalB
![Page 27: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/27.jpg)
Programa:Programa:
#include <stdio.h>#include <stdio.h>
char *a, *b;char *a, *b;
int func_A ()int func_A ()
{{
int local1, local2;int local1, local2;
- - - - - -
}}
void func_B ()void func_B ()
{ {
int localA, localB;int localA, localB;
localA = func_A();localA = func_A();
localB = func_A();localB = func_A();
}}
main ()main ()
{{
a = "Essa aula é legal";a = "Essa aula é legal";
b = "Será mesmo?"b = "Será mesmo?"
func_B();func_B();
}}
Sist.OperacionalSist.Operacional
"Essa aula é ..."Essa aula é ..."Será mesmo.."Será mesmo..
10010101...10010101...
aabb
HeapPointerTopo da ÁreaAlocável
StackPointerTopo da Pilha
Topo da Memória
Base da Memória
Variáveis estáticas
Código objeto
Constantes
&main-#3&main-#3localAlocalAlocalBlocalB
&func_B-#3&func_B-#3local1local1local2local2
![Page 28: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/28.jpg)
Programa:Programa:
#include <stdio.h>#include <stdio.h>
char *a, *b;char *a, *b;
int func_A ()int func_A ()
{{
int local1, local2;int local1, local2;
- - - - - -
}}
void func_B ()void func_B ()
{ {
int localA, localB;int localA, localB;
localA = func_A();localA = func_A();
localB = func_A();localB = func_A();
}}
main (...)main (...)
{{
a = "Essa aula é legal";a = "Essa aula é legal";
b = "Será mesmo?"b = "Será mesmo?"
func_B();func_B();
}}
Sist.OperacionalSist.Operacional
"Essa aula é ..."Essa aula é ..."Será mesmo.."Será mesmo..
10010101...10010101...
aabb
HeapPointerTopo da ÁreaAlocável
StackPointerTopo da Pilha
Topo da Memória
Base da Memória
Variáveis estáticas
Código objeto
Constantes
&main-#3&main-#3localAlocalAlocalBlocalB
&func_B-#2&func_B-#2local1local1local2local2
![Page 29: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/29.jpg)
Programa:Programa:
#include <stdio.h>#include <stdio.h>
char *a, *b;char *a, *b;
int func_A ()int func_A ()
{{
int local1, local2;int local1, local2;
- - - - - -
}}
void func_B ()void func_B ()
{ {
int localA, localB;int localA, localB;
localA = func_A();localA = func_A();
localB = func_A();localB = func_A();
}}
main (...)main (...)
{{
a = "Essa aula é legal";a = "Essa aula é legal";
b = "Será mesmo?"b = "Será mesmo?"
func_B();func_B();
}}
Sist.OperacionalSist.Operacional
"Essa aula é ..."Essa aula é ..."Será mesmo.."Será mesmo..
10010101...10010101...
aabb
HeapPointerTopo da ÁreaAlocável
StackPointerTopo da Pilha
Topo da Memória
Base da Memória
Variáveis estáticas
Código objeto
Constantes
&main-#3localAlocalB
![Page 30: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/30.jpg)
Programa:Programa:
#include <stdio.h>#include <stdio.h>
char *a, *b;char *a, *b;
int func_A ()int func_A ()
{{
int local1, local2;int local1, local2;
- - - - - -
}}
void func_B ()void func_B ()
{ {
int localA, localB;int localA, localB;
localA = func_A();localA = func_A();
localB = func_A();localB = func_A();
}}
main (...)main (...)
{{
a = "Essa aula é legal";a = "Essa aula é legal";
b = "Será mesmo?"b = "Será mesmo?"
func_B();func_B();
}}
aabb
aabb
10010101...10010101...10010101...10010101...
"Essa aula é ..."Essa aula é ..."Será mesmo.."Será mesmo..
"Essa aula é ..."Essa aula é ..."Será mesmo.."Será mesmo..
Sist.OperacionalSist.OperacionalSist.OperacionalSist.Operacional
HeapPointerInício da ÁreaAlocável
Topo da Memória
Base da Memória
Variáveis estáticas
Código objeto
Constantes
StackPointerInicio da Pilha
![Page 31: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/31.jpg)
Alocação Dinâmica
• void *malloc (tamanho numero_bytes)
– Retorna um ponteiro genérico para a área alocada
– Retorna NULL se não for possível alocar – Usar type casting para especificar um tipoV = (int *) malloc (sizeof (int));
if(v==NULL) “bye bye” … // if(!v) ...
![Page 32: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/32.jpg)
Sist.OperacionalSist.Operacional
10010101...10010101...
ppqq
HeapPointerTopo da ÁreaAlocável
StackPointerTopo da Pilha
Topo da Memória
Base da Memória
Variáveis estáticas
Código objeto
Constantes
1024 bytes1024 bytes
50*int = 200 bytes50*int = 200 bytes
ExemploExemplo::
#include <stdlib.h>#include <stdio.h>
char *p=NULL;int *q=NULL;
main (...){ p = (char *) malloc(1024);
// Aloca 1k // bytes de RAM
q = (int *) malloc(50*sizeof(int));
// Aloca espaço // para 50 inteiros.
}
![Page 33: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/33.jpg)
Alocação Dinâmica (2)
• void free (void *p)
– Devolve a memória previamente alocada para p
– O ponteiro p deve ter sido alocado dinamicamente
– Se p for NULL ==> sem efeito– Definição, mas sem inicialização; PERIGO!
int* p; free(p); ===> ERROint* p=NULL; free(p); ===> ok
![Page 34: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/34.jpg)
Ponteiros
• Permite o armazenamento e manipulação de endereços de memória
• Forma geral de declaração– tipo *nome ou tipo* nome– Símbolo * indica ao compilador que a variável
guardará o endereço da memória– Neste endereço da memória haverá um valor do
tipo especificado (tipo_do_ponteiro)– char *p; (p pode armazenar endereço de
memória em que existe um caractere armazenado)
– int *v; (v pode armazenar endereço de memória em que existe um inteiro armazenado)
– void *q; (ponteiro genérico)
![Page 35: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/35.jpg)
Recap: Ponteiros (2)
• Exemplo/*variável inteiro*/
int a;
/*variavel ponteiro para inteiro */
int* p;
/* a recebe o valor 5*/
a = 5;
/* p recebe o endereço de a */
p = &a;
/*conteúdo de p recebe o valor 6 */
*p = 6;
![Page 36: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/36.jpg)
Recap: Ponteiros (3)
• Exemplo#include <stdio.h>
#include <stdlib.h>
int main (int argc, char** argv)
{
int a;
int *p=NULL;
p = &a;
*p = 2;
printf (“a=%d “, a)
return EXIT_SUCCESS;
}
![Page 37: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/37.jpg)
Recap: Ponteiros (4)
• Exemplo...int main (...)
{
int a, b, *p = NULL;
a = 2;
*p = 3; // ERRO!
b = a + (*p);
printf (“ %d “, b);
return 0;
}
![Page 38: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/38.jpg)
Declarações que também são ponteiros
char nome[30];• Nome (sozinho) é um ponteiro para caractere que
aponta para o primeiro elemento do nome;
int v[20], *p;
p = &v[5]; *p = 0; // equivalente a fazer v[5] = 0
char nome[30]; char *apontaPraNome; ... apontaPraNome = nome; /* só o endereço */
![Page 39: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/39.jpg)
Operadores de ponteiros
• * indireção– Devolve o valor apontado pelo ponteiro
• & operador de endereço– Devolve o endereço na memória de seu operador
• Main (...){
int *aponta; int valor1, valor2; valor1 = 5;
aponta = &valor1; valor2 = *aponta;
}• Precedência: operadores & e * têm precedência maior
que outros operadores (com exceção do menos unário) int valor; int *aponta; valor = *aponta++
![Page 40: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/40.jpg)
Aritmética de ponteiros (1)• Atribuição
– Atribuição direta entre ponteiros passa o endereço de memória apontado por um para o outro.
int *p1, *p2, x;
x = 4;
p1 = &x;
p2 = p1;
![Page 41: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/41.jpg)
Aritmética de ponteiros (2)
• Nomes de funções são endereçosint main (...)
{
void *pmain = NULL;
pmain = main;
printf("pmain=%p\n", pmain );
...
![Page 42: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/42.jpg)
Aritmética de ponteiros (3)
• Adição e subtração
int *p1, *p2, *p3, *p4, x=0;p1 = &x;p2 = ++p1;p3 = p2 + 4;p4 = p3 - 5;
• Neste exemplo, p1, p2 e p3 apontam para endereços de memória que não estão associados com nenhuma variável. Neste caso, expressões do tipo *p1 *p2 e *p3 resultam em ERRO. O único endereço de memória acessível é o de x.
![Page 43: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/43.jpg)
Aritmética de ponteiros (4)
• Importante!– As operações de soma e subtração são baseadas
no tamanho do tipo base do ponteiro– Ex.: se p1 aponta para 2000, p1 + 2 vai apontar
para:• 2002, se o tipo base do ponteiro for char (1 byte)• 2008, se o tipo base do ponteiro for int (4 bytes)
– Ou seja, este exemplo de soma significa que o valor de p1 é adicionado de duas vezes o tamanho do tipo base.
![Page 44: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/44.jpg)
Aritmética de ponteiros (5)
• No exemplo anterior, se o endereço de x é 1000: – p1 recebe o valor 1000
(endereço de memória de x)– p2 recebe o valor 1004
e p1 tem seu valoratualizado para 1004.
– p3 recebe o valor 1004 + 4 * 4 = 1020. – p4 recebe o valor 1020 - 5 * 4 = 1000.
• Se o tipo base dos ponteiros acima fosse char* (1 byte), os endereços seriam, respectivamente: 1001, 1001, 1005 e 1000.
x=0;p1 = &x;p2 = ++p1;p3 = p2 + 4;p4 = p3 - 5;
![Page 45: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/45.jpg)
Aritmética de ponteiros (6)
• Explique a diferença entre: (int *p) p++; (*p)++; *(p++);
• Comparação entre ponteiros (verifica se um ponteiro aponta para um endereço de memória maior que outro)
int *p; *q;
...
if (p < q)
printf (“p aponta para um endereço menor que o de q”);
![Page 46: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/46.jpg)
Ponteiros, Vetores e Matrizes
• Ponteiros, vetores e matrizes são muito relacionados em C
• Já vimos que vetores também são ponteiros. – char nome[30]– nome sozinho é um ponteiro para caractere, que
aponta para a primeira posição do nome
• As seguintes notações são equivalentes:– variável[índice]– *(variável+índice)- variável[0] equivale a *variável !
![Page 47: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/47.jpg)
Exemplo#include <stdio.h>#include <stdlib.h>#include <string.h>
int main (int argc, char** argv){
charnome[30] = "José da Silva";char*p1, *p2; char car; int i;p1 = nome;car = nome[2];printf( "car=%c\n", car);car = p1[0];printf( "car=%c\n", car);p2 = &nome[5];printf( "p2=>>>%s<<<\t= %p\n", p2, p2);p2 = p1;p2 = p1 + 5;printf( "p1+5=>>>%s<<<\t= %p\n", (p1+5), (p1+5));printf( "p1+20>>>%s<<<\t\t= %p\n", (p1+20),
(p1+20));for (i=0; i<strlen(nome); i++) {
printf ("%c", nome[i]); p2 = p1 + i;printf ("%c", *p2);
}printf("\n");return EXIT_SUCCESS; }
car=scar=Jp2=>>> da Silva<<< = 0x7fff741910f5p1+5=>>> da Silva<<< = 0x7fff741910f5p1+20>>><<< = 0x7fff74191104JJooss ddaa SSiillvvaa���
![Page 48: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/48.jpg)
Exemplo#include <stdio.h>#include <stdlib.h>#include <string.h>
int main (int argc, char** argv){
charnome[30] = "José da Silva";char*p1, *p2; char car; int i;p1 = nome; // nome sozinho é um ponteirocar = nome[2]; // Atribuição de 's' a car.printf( "car=%c\n", car);car = p1[0]; // Atribuição de 'J' a car.printf( "car=%c\n", car);p2 = &nome[5]; // 6a posição (='') de nome a p2.
No caso de José com acento = ' ', sem = 'd';printf( "p2=>>>%s<<<\t= %p\n", p2, p2);p2 = p1;p2 = p1 + 5;printf( "p1+5=>>>%s<<<\t= %p\n", (p1+5), (p1+5)); printf( "p1+20>>>%s<<<\t\t= %p\n", (p1+20),
(p1+20));for (i=0; i<strlen(nome); i++) {
printf ("%c", nome[i]); p2 = p1 + i;printf ("%c", *p2);
}printf("\n");return EXIT_SUCCESS; }
car=scar=Jp2=>>> da Silva<<< = 0x7fff741910f5p1+5=>>> da Silva<<< = 0x7fff741910f5p1+20>>><<< = 0x7fff74191104JJooss ddaa SSiillvvaa���
![Page 49: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/49.jpg)
Matrizes de ponteiros
• Ponteiros podem ser declarados como vetores ou matrizes multidimensionais. Exemplo:
int *vetor[30]; /* Vetor de 30 ponteiros /* para números inteiros */int a=1, b=2, c=3; vetor[0] = &a; /* vetor[0] aponta para a*/vetor[1] = &b;vetor[2] = &c;/* Imprime "a: 1, b: 2"... */printf ( "a: %d, b: %d", *vetor[0], *vetor[1] );
===> a: 1, b: 2
![Page 50: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/50.jpg)
Matrizes de ponteiros (2)
• Importante: – Quando alocamos um vetor de ponteiros para
inteiros, não necessariamente estamos alocando espaço de memória para armazenar os valores inteiros!
• No exemplo anterior, alocamos espaço de memória para a, b e c (3 primeiras posições do vetor apontam para as posições de memória ocupadas por a, b, e c)
![Page 51: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/51.jpg)
Matrizes de ponteiros
• Matrizes de ponteiros são muito utilizadas para manipulação de strings. Por exemplo:
char *mensagem[] = {/* vetor inicializado */ "arquivo não encontrado", "erro de leitura", "erro de escrita", "impossível criar arquivo" };void escreveMensagemDeErro (int num) { printf ("%s\n", mensagem[num]); }main () { escreveMensagemDeErro( 3 ); }
%s imprime a string até encontrar o car.
“\0”
![Page 52: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/52.jpg)
Matrizes de ponteiros (2)
• Manipular inteiros é um pouco diferente:
int *vetor[40];void imprimeTodos () { int i; for (i=0; i < 40; i++)
printf ("%d\n", *vetor[i]); }
• *vetor[i] equivale a **(vetor +i)• Vetor aponta para um ponteiro que aponta para o
valor do inteiro• Indireção Múltipla ou Ponteiros para Ponteiros
![Page 53: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/53.jpg)
Ponteiros para Ponteiros ou Indireção Múltipla
• Podemos usar ponteiros para ponteiros implicitamente, como no exemplo anterior
• Também podemos usar uma notação mais explícita, da seguinte forma:– tipo **variável;
• **variável é o conteúdo final da variável apontada;
• *variável é o conteúdo do ponteiro intermediário.
![Page 54: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/54.jpg)
Ponteiros para Ponteiros (2)
#include <stdio.h>main (...){ int x, *p, **q; x = 10; p = &x; // p aponta para x q = &p; // q aponta para p printf ("%d\n", **q); // imprime 10...}
![Page 55: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/55.jpg)
Explique o comportamento do seguinte programa:
![Page 56: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/56.jpg)
#include <stdio.h>char *a = "Bananarama";char b[80] = "uma coisa boba";char *c[5];
/* Recebe vetor de ponteiros para caractere de tamanho indefinido */void teste1 (char *d[] ) { printf( "Teste1: d[0]:%s e d[1]:%s\n\n", d[0], d[1]); }
/* Recebe ponteiro para ponteiro para caractere */void teste2 (char **d ) {
printf( "Teste2: d[0]:%s e d[1]:%s\n", d[0], d[1]); printf( "Teste3: d[0]:%s e d[1]:%s\n", *d, *(d + 1)); }
main (...) { c[0] = a; c[1] = b; printf( "a: %s e b: %s\n\n", a, b); printf( "c[0]: %s e c[1]: %s\n\n", c[0], c[1]); teste1 ( c ); teste2 ( c );}
![Page 57: Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores 09/04/2014](https://reader036.vdocuments.site/reader036/viewer/2022062512/552fc182497959413d8f44f7/html5/thumbnails/57.jpg)
a: Bananarama e b: uma coisa boba
c[0]: Bananarama e c[1]: uma coisa boba
Teste1: d[0]:Bananarama e d[1]:uma coisa boba
Teste2: d[0]:Bananarama e d[1]:uma coisa bobaTeste3: d[0]:Bananarama e d[1]:uma coisa boba