Programação Estruturada Prof. Rodrigo Hausen Organização e Gerenciamento de Memória

Documentos relacionados
Programação Estruturada Prof. Rodrigo Hausen Ponteiros e Passagem de Parâmetros

Alocação Dinâmica de Memória. Programação II

INF 1007 Programação II

Exercício. Alocação Dinâmica. Alocação dinâmica de memória. Alocação de memória. Alocação da Memória Principal. Alocação da Memória Principal

Aula 25: Alocação Dinâmica

Programação Estruturada Prof. Rodrigo Hausen Agregados de Dados Heterogêneos (structs)

Estruturas de Dados Aulas 3 e 4: Uso da. 14/03/2011 e 16/03/2011

Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores

MC-102 Aula 19 Ponteiros II

Ponteiros e Alocação de Memória

Ponteiros. prof. Fabrício Olivetti de França

A sintaxe para se declarar uma variável do tipo ponteiro é dada por:

Alocação Dinâmica em C

Exercícios. Alocação Dinâmica. Alocação dinâmica de memória. Alocação de memória. Alocação da Memória Principal. Alocação da Memória Principal

Módulo 5 Vetores e Alocação Dinâmica

Ponteiros. Baseado nos slides do Prof. Mauro.

Aula 07: - Mapa de memória de um processo - Ponteiros (parte 1)

MCTA028 Programação Estruturada Aula 09: - Ponteiros (parte 2)

Programação I Ponteiros e alocação dinâmica de memória. Prof. Carlos Alberto

Alocação Dinâmica. Introdução à Computação

Estruturas de Dados. Introdução Definição de Ponteiros Declaração de Ponteiros em C Manipulação de Ponteiros em C

Ponteiros e alocação dinâmica de memória. Disciplina de Programação de Computadores I Universidade Federal de Ouro Preto

Programação Estruturada

- Mapa de memória de um processo - Ponteiros

INF1007: Programação 2. 2 Alocação Dinâmica. 17/02/2014 (c) Dept. Informática - PUC-Rio 1

ALGORITMOS E ESRUTRA DE DADOS I. Ponteiros Passagem por Valor e Referência Alocação de Memória

MCTA028 Programação Estruturada Aula 09: - Ponteiros (parte 2)

11a. Aula Ponteiros e Vetores

Programação de Computadores II. Cap. 5 Alocação Dinâmica

Reinaldo Gomes Alocação Dinâmica

Curso de Programação C em Ambientes Linux Aula 05

Ponteiros de Variáveis

BCC202 - Estrutura de Dados I

Estruturas de Dados. Profa. Juliana Pinheiro Campos

Universidade Federal de Uberlândia Faculdade de Computação. Linguagem C: ponteiros e alocação dinâmica

Princípios de Desenvolvimento de Algoritmos MAC122

Linguagem C: Introdução

Tipos Básicos. Operadores de Incremento e Decremento. Operador Sizeof. Estruturas de Dados Aula 2: Estruturas Estáticas

Estruturas de Dados Aula 2: Estruturas Estáticas. Tipos Básicos. Quantos valores distintos podemos representar com o tipo char?

Estruturas de Dados Aula 2: Estruturas Estáticas 02/03/2011

Estrutura de dados 1. Ponteiros

Introdução a Programação de Jogos

Programação II. Vetores e Alocação Dinâmica. Bruno Feijó Dept. de Informática, PUC-Rio

Programação Estruturada Prof. Rodrigo Hausen Vetores (Arrays)

Laboratório de Programação II

PONTEIROS E LISTAS. Kalinka Regina Lucas Jaquie Castelo Branco

Introdução a Programação. Ponteiros e Vetores, Alocação Dinâmica

Fundamentos de Programação

Introdução. Ponteiros

13. ALOCAÇÃO DINÂMICA DE MEMÓRIA

Ponteiros em C. Adriano Joaquim de Oliveira Cruz 21 de julho de Instituto de Matemática Departamento de Ciência da Computação UFRJ

LINGUAGEM C: ALOCAÇÃO DINÂMICA

Estrutura de Dados. Aula 07 Alocação Dinâmica

ponteiros INF Programação I Prof. Roberto Azevedo

A linguagem C permite dois tipos de alocação de memória: Alocação estática e alocação dinâmica.

Computadores Digitais 2. Prof. Rodrigo de Souza Couto

Algoritmos e Estruturas de Dados. Prof. Marcelo Zorzan Profa. Melissa Zanatta

Estruturas Dinâmicas - Ponteiros

Bruno Hott Algoritmos e Estruturas de Dados I DECSI UFOP. Alocação Dinâmica de Memória

Modulo 12: alocação dinâmica de memória

Introdução a Programação. Ponteiros e Strings, Alocação Dinâmica

Algoritmos e Estruturas de dados

Programação: Vetores

Fundamentos de Programação

NOTAS DE AULA 09 Estruturas e Ponteiros

Algoritmos e Programação

3. Linguagem de Programação C

Aula 17: Ponteiros e Alocação Dinâmica em C

Ponteiros em C. Prof. Rui Jorge Tramontin Jr. UDESC - Rui J. Tramontin Jr. 1

DAS5102 Fundamentos da Estrutura da Informação

MCTA001 Algoritmos e Estruturas de Dados I Aula 02: Ponteiros e estruturas

SSC304 Introdução à Programação Para Engenharias. Alocação Dinâmica. GE4 Bio

Laboratório de Programação II

Programação Computacional Aula 16: Alocação Dinâmica de Memória

Variáveis e Operadores em C

ALOCAÇÃO DINÂMICA DE MEMORIA Lista 10. A linguagem C/C++ possui recursos para alocação dinâmica de memoria.

Linguagem C: Ponteiros - Alocação Dinâmica

Programação II. Vetores e Alocação Dinâmica. Bruno Feijó Dept. de Informática, PUC-Rio

Alocação Estática e Dinâmica. Prof. M.Sc. Mariella Berger

Introdução à Ciência da Computação I. Alocação Dinâmica. Prof. Claudio Fabiano Motta Toledo

Programação de Computadores I Introdução ao C PROFESSORA CINTIA CAETANO

1 Exercícios com ponteiros

Alocação Dinâmica de Memória

Estruturas da linguagem C. 1. Identificadores, tipos primitivos, variáveis e constantes, operadores e expressões.

Programação Imperativa. Lição n.º 16 A pilha de execução

12 - Dados Estruturados Vetores, Matrizes e Strings

Estrutura de dados 2. Ponteiro. Prof. Jesuliana N. Ulysses

Alocação de Memória. Lucas Ferrari de Oliveira Professor Adjunto Universidade Federal do Paraná (UFPR)

Bruno Hott Algoritmos e Estruturas de Dados I DECSI UFOP. Alocação Dinâmica de Memória

Linguagem C Ponteiros

Linguagem C. Ponteiros. Alex Vidigal Bastos.

Sumário. Introdução à Ciência da Computação. Ponteiros em C. Introdução. Definição. Por quê ponteiros são importantes?

Professor: Jó Ueyama Estagiário PAE: Heitor Freitas

ESTRUTURA DE DADOS (TCC )

ALOCAÇÃO DINÂMICA DE MEMÓRIA

5. Vetores e alocação dinâmica

Computação 2. Aula 7. Profª. Fabiany Ponteiros

Transcrição:

Programação Estruturada Prof. Rodrigo Hausen http://progest.compscinet.org Organização e Gerenciamento de Memória 1

AULA PASSADA - vetores ou arrays Declaração de um vetor (array) em C: tipo nome[tamanho]; Exemplos: int numeros[100]; double notas[40]; char nomedomes[10]; Obs.: padrão C99 permite definir vetores com tamanho dependente de variável int n = 40; double notas[n]; 2

VETORES Acesso a elemento: nomedoarray[posicao] Obs.: em C, a posição do primeiro elemento de um array é sempre 0 (zero) Inicialização com atribuição: int numeros[] = { 7, 9, 5, 2, 1 ; 3

VETORES e ORGANIZAÇÃO DA MEMÓRIA Exemplo: crie o programa testevetor.c com o seguinte conteúdo. Compile com o gcc e execute-o na máquina virtual. #include <stdio.h> int main(void) { int a[] = { 18, 33, 99 ; int b[] = { 42, 21 ; int i; for (i=0; i<7; ++i) { printf("b[%d] = %d\n", i, b[i]); 4

VETORES e ORGANIZAÇÃO DA MEMÓRIA int a[] = { 18, 33, 99 ; int b[] = { 42, 21 ; b[0] = 42 b[1] = 21 b[2] = 4195344 b[3] = 0 b[4] = 18 b[5] = 33 b[6] = 99 5

VETORES e ORGANIZAÇÃO DA MEMÓRIA int a[] = { 18, 33, 99 ; int b[] = { 42, 21 ; Moral da história: C não verifica se estamos acessando posições fora dos limites do vetor! elementos de um vetor ocupam posições contíguas na memória b[0] = 42 b[1] = 21 b[2] = 4195344 b[3] = 0 b[4] = 18 b[5] = 33 b[6] = 99 6

VETORES e ORGANIZAÇÃO DA MEMÓRIA Elementos de vetores declarados com tipo nomevet[tamanho]; ou com tipo nomevet[] = { elmt0, elmt1, ; ocupam posições subsequentes da memória do computador, geralmente na área denominada pilha. A variável nomevet apenas armazena a posição (endereço) do primeiro elemento. Vamos alterar o programa para imprimir os endereços dos elementos do vetor. 7

VETORES e ORGANIZAÇÃO DA MEMÓRIA // testevetor2.c #include <stdio.h> int main(void) { int a[] = { 18, 33, 99 ; int b[] = { 42, 21 ; int i; printf("a em %p e b em %p\n", a, b); for (i=0; i<7; ++i) { printf("%p: b[%d]=%d\n",&b[i],i,b[i]); 8

VETORES e ORGANIZAÇÃO DA MEMÓRIA #include <stdio.h> int main(void) { int a[] = { 18, 33, 99 ; int b[] = { 42, 21 ; int i; printf("a em %p e b em %p\n", a, b); for (i=0; i<7; ++i) { printf("%p: b[%d]=%d\n",&b[i],i,b[i]); formato %p imprime endereço em hexadecimal operador unário & obtém endereço de variável

VETORES e ORGANIZAÇÃO DA MEMÓRIA int a[] = { 18, 33, 99 ; int b[] = { 42, 21 ; a em 0x7fff67957920 e b em 0x7fff67957910 0x7fff67957910: b[0] = 42 0x7fff67957914: b[1] = 21 0x7fff67957918: b[2] = 4195344 0x7fff6795791c: b[3] = 0 0x7fff67957920: b[4] = 18 0x7fff67957924: b[5] = 33 0x7fff67957928: b[6] = 99 Obs.: não posso assumir que os endereços serão os mesmos em outros computadores, ou com outros compiladores, ou mesmo em outras execuções! 10

VETORES e ORGANIZAÇÃO DA MEMÓRIA A memória do computador pode ser vista como um conjunto de caixinhas. Cada uma pode ser acessada por meio de seu endereço. 0x0???????? 0x4???????? 0x8???????? 0x7fff67957910 42 b[0] 0x7fff67957914 21 b[1] 0x7fff67957918???????? 0x7fff6795791c???????? 0x7fff67957920 18 a[0] 0x7fff67957924 33 a[1] 0x7fff67957928 99 a[2] Obs.: lembre que os endereços são específicos desta máquina, compilador e execução Se você executar o mesmo programa em outro computador, os resultados podem ser diferentes! Só é garantido que um vetor ocupe área de memória contígua!

VETORES e PONTEIROS Vimos que vetor é apenas uma referência para uma posição de memória. Podemos criar variáveis que, explicitamente, armazenam uma referência para outra posição de memória. Tais variáveis são chamadas ponteiros. Declaração de um ponteiro: tipo *nome; 12

VETORES e PONTEIROS Para que uma função retorne um vetor, devemos declarar o tipo de retorno como ponteiro. Exemplo: função para calcular e retornar a soma de dois vetores v, w. Vamos fazer uma primeira tentativa. Note que o código a seguir compila, mas está errado! 13

// somavetores.c // este código compila mas está errado!! double *somavetores(double v[], double w[], int n) { double soma[n]; int i; for (i = 0; i < n; ++i) { soma[i] = v[i] + w[i]; return soma; 14

[cling]$.l somavetores.c warning: address of stack memory associated with local variable 'ret' returned [-Wreturn-stackaddress] return ret; ^~~ [cling]$ double v[] = { 1.5, 2.4, 3.1 ; [cling]$ double w[] = { 4.0, 6.3, 8.2 ; [cling]$ double *z = somavetores(v,w,3); [cling]$ z[0] (double) ( lixo ) [cling]$ z[1] (double) ( lixo ) [cling]$ z[2] (double) ( lixo ) 15

[cling]$.l somavetores.c warning: address of stack memory associated with local variable 'ret' returned [-Wreturn-stackaddress] return ret; ^~~ [cling]$ double v[] = { 1.5, 2.4, 3.1 ; [cling]$ double w[] = { 4.0, 6.3, 8.2 ; [cling]$ double *z = somavetores(v,w,3); [cling]$ z[0] (double) ( lixo ) [cling]$ z[1] (double) ( lixo ) [cling]$ z[2] (double) ( lixo ) Não deveriam ser, respectivamente, 5.5, 8.7 e 11.3? 16

VETORES e PONTEIROS Relembrando: vetores declarados com tipo nome[tam]; são geralmente declarados na área de memória chamada pilha. A parte da pilha alocada a uma função não é mais válida após o término dessa função. Precisamos alocar espaço para vetores em outra área de memória. Como fazer? 17

ORGANIZAÇÃO DA MEMÓRIA em C Para a linguagem C, a memória é organizada em duas áreas principais: a pilha, região onde, para cada bloco de código, o espaço no topo é automaticamente reservado (alocado) para variáveis locais e, ao final do bloco, automaticamente liberado (desalocado). o heap (amontoado), onde a alocação e desalocação de memória é gerenciada manualmente pelo programador. 18

GERENCIAMENTO MANUAL DE MEMÓRIA Em C, o gerenciamento manual de memória é feito por meio de funções encontradas na biblioteca stdlib.h As principais são: malloc, que recebe o número de bytes a serem alocados e retorna o endereço inicial da região de memória alocada Ou 0 (NULL) caso não haja memória disponível. free, que recebe o endereço inicial de uma região alocada por malloc e marca a região como disponível para futuras Alocações. 19

Voltando à implementação incorreta de somavetores: double *somavetores(double v[], double w[], int n) { double soma[n]; int i; for (i = 0; i < n; ++i) { soma[i] = v[i] + w[i]; vetor soma alocado na pilha. Esta região de memória é desalocada automaticamente ao final da função. return soma; 20

#include <stdlib.h> double *somavetores(double v[], double w[], int n) { double *soma = (double *) malloc(n * sizeof(double)); int i; if (soma == NULL) return NULL; for (i = 0; i < n; ++i) { soma[i] = v[i] + w[i]; return soma; 21

#include <stdlib.h> double *somavetores(double v[], double w[], int n) { double *soma = (double *) malloc(n * sizeof(double)); int i; if (soma == NULL) return NULL; for (i = 0; i < n; ++i) { soma[i] = v[i] + w[i]; carrega biblioteca com a função malloc return soma; 22

#include <stdlib.h> double *somavetores(double v[], double w[], int n) { double *soma = (double *) malloc(n * sizeof(double)); int i; if (soma == NULL) return NULL; Calcula espaço em bytes for (i = 0; i < n; para ++i) um { vetor de n soma[i] = v[i] + elementos w[i]; do tipo double return soma; 23

#include <stdlib.h> double *somavetores(double v[], double w[], int n) { double *soma = (double *) malloc(n * sizeof(double)); int i; O ponteiro retornado por malloc é do tipo if void (soma * (ponteiro == NULL) sem return tipo). NULL; É preciso convertê-lo para o tipo de ponteiro for (i desejado. = 0; i < n; ++i) { soma[i] = v[i] + w[i]; return soma; 24

#include <stdlib.h> double *somavetores(double v[], double w[], int n) { double *soma = (double *) malloc(n * sizeof(double)); int i; if (soma == NULL) return NULL; for (i = 0; i < n; ++i) { soma[i] = v[i] + w[i]; Antes de usar, SEMPRE verifique se o ponteiro retornado por malloc é return soma; nulo! Se for nulo, trate a situação da melhor maneira possível. 25

CUIDADOS COM O GERENCIAMENTO DE MEMÓRIA para cada malloc deve existir um, e apenas um, free correspondente esquecer free falta de memória no futuro double free = KABOOM! (a execução do seu programa é abortada imediatamente) jamais use um ponteiro após executar free nele! Fácil de falar, mas ocorre muitas vezes por descuido. Erros de uso de ponteiro após free costumam ser difíceis de depurar pois podem causar efeitos colaterais aparentemente inexplicáveis e longe da origem. 26

CUIDADOS COM O GERENCIAMENTO DE MEMÓRIA se uma função retorna um ponteiro alocado com malloc, SEMPRE informe na documentação da função que você deverá usar free no ponteiro retornado /** * Soma dois vetores. * IMPORTANTE: o ponteiro retornado * deverá ser liberado com free após * o uso. */ double *somavetores(double v[], double w[], int n) { 27

CUIDADOS COM O GERENCIAMENTO DE MEMÓRIA enquanto estiver escrevendo código que usa malloc, ou código que usa uma função que retorna ponteiro alocado desta forma, escreva imediatamente o free após o uso, para não esquecer dele, e depois coloque o resto do código entre a alocação e o free. 28

EXERCÍCIOS Crie um arquivo strfunc.c, implemente e documente as seguintes funções, com atenção para todos os casos possíveis (inclusive ponteiros nulos) int comprimento(const char *s) retorna o número de caracteres da string (sem incluir o caractere nulo) char *concatena(const char *s1, const char *s2) retorna a concatenação de s1 com s2. char *maiusculas(const char *s) retorna a string trocando os caracteres a-z para maiúsculas 29

OBSERVAÇÃO Por que o uso de const char *? int comprimento(const char *s) char *concatena(const char *s1, const char *s2) char *maiusculas(const char *s) Isto indica que as áreas de memória indicadas pelos parâmetros não serão alteradas pela função. BOA PRÁTICA: funções que recebem ponteiros e que não alteram as regiões apontadas por eles devem declará-los como const. 30

Mais exercícios serão colocados no site. Façam os exercícios e estudem! Sempre testem suas implementações de funções no cling. Pensem em exemplos para testá-las e casos patológicos (strings vazias, ponteiros nulos caso sejam permitidos, parâmetros inteiros iguais a zero ou negativos, etc.) Vou colocar no final de semana uma imagem live do ambiente de desenvolvimento (compilador, cling e IDE) que executa direto de um pendrive sem precisar de instalação. 31