• Nenhum resultado encontrado

- Mapa de memória de um processo - Ponteiros

N/A
N/A
Protected

Academic year: 2022

Share "- Mapa de memória de um processo - Ponteiros"

Copied!
63
0
0

Texto

(1)

- Mapa de memória de um processo - Ponteiros

MCTA028 – Programação Estruturada

Luiz Rozante 3Q-2018

Material preparado a partir de slides dos profs. Jesús Mena-Chalco e Fabrício Olivetti

(2)

Alocação de memória

Na execução, um programa é um processo.

(processos de SOs são módulos executáveis únicos) Um processo ocupa parte da memória principal, reservada para:

instruções, dados,

pilha, heap

O espaço de endereços de um processo em execução é

dividido nessas 4 áreas (as mais importantes)

(3)

Alocação de memória

Modelo geral de organização da memória:

(4)

Alocação de memória

Text area: contém o código do programa e suas constantes.

Esta área é alocada durante a chamada exec e permanece do mesmo tamanho durante toda a vida do processo.

Data area: é a memória de trabalho do processo, onde ele

armazena suas variáveis globais e estáticas. Tem tamanho fixo ao longo da execução do processo.

Stack area: contém a pilha de execução, onde são

armazenadas os parâmetros, endereços de retorno e variáveis locais de funções. Pode variar de tamanho durante a execução do processo.

Heap area: contém áreas de memória alocadas a pedido do processo, durante sua execução. Varia de tamanho durante a vida do processo.

(5)

Alocação de memória

Um processo C suporta três tipos de alocação de memória::

A alocação estática ocorre quando são declaradas variáveis globais ou estáticas; geralmente usa a área Data.

A alocação automática ocorre quando são declaradas variáveis locais e parâmetros de funções. O espaço para a alocação

dessas variáveis é reservado quando a função é invocada, e liberado quando a função termina. Geralmente é usada a pilha (stack).

A alocação dinâmica, quando o processo requisita

explicitamente um bloco de memória para armazenar dados; o controle das áreas alocadas dinamicamente é manual ou

semi-automático: o programador é responsável por liberar as

áreas alocadas dinamicamente. A alocação dinâmica geralmente usa a área de heap.

(6)

Alocação estática

Ocorre com variáveis globais (alocadas fora de funções) .

Ocorre quando variáveis locais (internas a uma função) são alocadas usando o modificador static.

Uma variável alocada estaticamente mantém seu valor durante toda a vida do programa, exceto quando

explicitamente modificada.

(7)

Alocação automática

As variáveis definidas dentro de uma função (variáveis locais e parâmetros) são alocadas de forma automática na pilha de execução do programa (stack) a cada

chamada da função.

São descartadas quando a função encerra.

Pilha de execução geralmente é uma área pequena.

(problema para variáveis locais muito grande e funções

recurcivas)

(8)

Alocação dinâmica

O programa (processo) solicita explicitamente áreas de memória ao SO.

Depois de utilizá-las as libera quando não são mais necessárias.

- depois de liberado, espaço estará disponibilizado para outros usos e não pode mais ser acessado

- espaço alocado e não liberado explicitamente, será automaticamente liberado ao final da execução

As requisições de memória dinâmica são geralmente

alocadas na área heap.

(9)

INSTRUÇÕES PILHA (STACK)

Processo na memória

HEAP

Fenômeno: Stack Overflow

Quando temos variáveis locais muito grande ou muitas chamadas recursivas

(10)

INSTRUÇÕES PILHA (STACK)

Processo na memória

HEAP

Como resolver?

Em Java e Python o uso é transparente.

Não precisa se preocupar de alocar e

(11)

Endereços e ponteiros

(ferramentas para fazer alocação dinâmica)

(12)

Endereços e ponteiros

Os conceitos de endereço e ponteiro são fundamentais em qualquer linguagem de programação.

Na linguagem C é mais visível este conceito.

Requer um esforço para usar os ponteiros.

(13)

Endereços

A memória de qualquer computador (arquitetura de von Neumann) é uma sequência de bytes.

Cada byte armazena um de 256 possíveis valores

Os bytes são numerados sequencialmente e o número de um

byte é o seu endereço

(14)

Endereços

(15)

Endereços

...

01010111 11000011 01100100 11100010

...

37FD00 37FD01 37FD02 37FD03

Geralmente o endereço do objeto é o endereço do 1ro byte.

(16)

Endereços e ponteiros

Em C o endereço de um objeto é dado pelo operador &

Se x é uma variável, então &x é o seu endereço

int s = -999

0x89422 -9999

s

(17)

Endereços e ponteiros

Em c o endereço de um objeto é dado pelo operador &

Se x é uma variável, então &x é o seu endereço

int s = -9999

int *p = &s //(ou int *p; p=&s;)

0x89422 0x60001

p

p = 0x89422

&p = 0x60001

-9999 0x89422

*p = -9999

s

“p aponta para a s”

“p é o endereço de s”

“p aponta a s”

*p é o mesmo que escrever “s” (*p=``conteúdo apontado por p”)

(18)

Endereços e ponteiros

4 8

Os ponteiros são variáveis de 2 a 8 bytes (dependendo

do computador) que armazenam um endereço de memória.

(19)

Endereços

Todo ponteiro pode ter o valor NULL.

NULL é uma constante, geralmente vale 0 (definida no arquivo interface stdlib)

0 0x564320

p

int *p = NULL; /* não aponta o dedo pra ninguém */

0x00000

(20)

Endereços

Há vários tipos de ponteiros:

P. para caracteres P. para inteiros

P. para registros

P. para ponteiros para inteiros

int* p ; int *p;

int * p;

← O “*” modifica a variável e não o int (mais aceito)

← Um tipo de dado novo int* (conceitualmente correto)

(21)

exemploPonteiro1.c

Operadores unarios

& → Referência: na frente de uma variável:

Devolve o endereço de memória onde a variável está armazenada

* → Derreferência: na frente de variável ou expressão:

Devolve o valor ou conteúdo do endereço de memória apontada pela variável ou expressão

(22)

exemploPonteiro2.c

Conteúdo apontado pelo endereço de i

(23)

exemploPonteiro3.c

Passagem de parâmetros por valor:

(24)

exemploPonteiro3.c

Passagem de parâmetros por referência:

(25)

exemploPonteiro3.c

Por que o código abaixo está errado?

(26)

exemploPonteiro3.c

Por que o código abaixo está errado?

Porque temp é um ponteiro para o qual não foi atribuído um endereço

“que conhecemos”: ele contém um endereço de memória que não pertence a nenhuma das variáveis que criamos.

(27)

Vetores e endereços

(28)

Vetores

Os elementos de um vetor são alocados consecutivamente na memória do computador.

Se cada elemento ocupa b bytes, a diferença entre os endereços de dois elementos consecutivos será de b.

(ex. inteiros ocupam 4 bytes, em uma plataforma de 64 bits)

(29)

Vetores

Os elementos de um vetor são alocados consecutivamente na memória do computador.

Se cada elemento ocupa b bytes, a diferença entre os endereços de dois elementos consecutivos será de b.

O compilador C cria a ilusão de que b vale 1 qualquer que seja o tipo dos elementos do vetor.

(30)

Vetores e ponteiros

(31)

Vetores e ponteiros

vetor

...

...

(32)

Vetores e ponteiros

...

...

(33)

Alocação dinâmica

(void *) malloc( size );

size: tamanho (número de bytes a alocar)

malloc aloca um bloco de bytes consecutivos na memória heap

void * : endereço devolvido por malloc

void * : ponteiro do tipo void é utilizado para referenciar

um tipo genérico, que pode ser transformado em qualquer

outro tipo.

(34)

Alocação dinâmica

(35)

Alocação dinâmica

(36)

Alocação dinâmica

(37)

Alocação dinâmica

Ideia V+i*sizeof(int)

(38)

Alocação dinâmica

(39)

Quando não for possível Separar memoria suficiente Um ponteiro NULO é devolvido

A função malloc não assegura que o espaço de

memória foi realmente alocado, por isso é importante verificar se o ponteiro é diferente de NULL antes usá-lo!

(40)

Quando não for possível Separar memoria suficiente Um ponteiro nulo é devolvido

A diferença de ponteiros

(41)

Alocação dinâmica

uma vez alocado o espaço, não existe garantias do

valor inicial dos elementos da array!!

(42)

Os ponteiros facilitam a alocação dinâmica

de memória

Após o uso e antes de terminar o programa, devemos liberar a memória para que ela seja utilizada por outros

(43)

Matrizes

Material adaptado da aula de Matrizes de Ronaldo F. Hashimoto e Carlos H. Morimoto (IME/USP)

(44)

Declara uma matriz M de 100 linhas com 200 colunas

(20mil inteiros)

(45)

Estrutura da matriz na memória do computador

(46)

Disposição dos 20mil elementos da matriz M na memória

(47)

Disposição dos 20mil elementos da matriz M na memória

Qual o endereço de M[0][78]?

(tendo como base M[0][0]) &M[0][0]+78

(48)

Disposição dos 20mil elementos da matriz M na memória

(49)

Disposição dos 20mil elementos da matriz M na memória

Qual o endereço de M[78][21]?

(tendo como base M[0][0]) &M[0][0] + (78*200+21)

(50)

Índices

Na linguagem C não existe verificação de índices fora da matriz/vetor.

Quem deve controlar o uso correto dos índices é o programador.

O acesso utilizando um índice errado pode ocasionar o acesso de outra variável na memória.

→ Se o acesso à memória é indevido você recebe a mensagem “segmentation fault”.

(51)

Matrizes

(52)

Matrizes

(53)
(54)

Matrizes

A alocação dinâmica de memória para matrizes é realizada da mesma forma que para vetores.

A diferença é que temos um ponteiro apontando para outro ponteiro que aponta para o “valor final”.

Ou seja é um ponteiro para ponteiro (indireção múltipla).

A indireção múltipla pode ser levada a qualquer

dimensão desejada, mas raramente é necessário mais de um ponteiro para um ponteiro.

(55)

Matrizes

A estrutura de dados utilizada é composta por um vetor de ponteiros (correspondendo ao

primeiro índice da matriz), sendo que cada ponteiro aponta para o início de uma linha da matriz.

Em cada linha existe um vetor alocado

dinamicamente, como descrito anteriormente

(compondo o segundo índice da matriz).

(56)

Matrizes

Matrizes (bidimensionais) são implementadas como vetores de vetores.

Exemplo de trecho de código para alocar uma

matriz M com m linhas e n colunas:

(57)

Atividade em aula

(58)

Questão 1 - a

Escreva o resultado da execução do seguinte programa

(59)

Questão 1 - b

Escreva o resultado da execução do seguinte programa

(60)

Questão 1 - c

(61)

Função com matriz como parâmetro

O nome de uma matriz dentro do parâmetro de uma função é utilizado como sendo um ponteiro para o primeiro

elemento da matriz que está sendo usada na hora de utilizar a função.

→ Não é alocada memória (novamente) para um vetor passado por parâmetro para uma função.

(62)

Questão 2

Escreva um programa que leia um número inteiro positivo n seguido de n números inteiros e imprima esses n números em ordem

invertida.

Por exemplo, ao receber 5

22 33 44 55 66

o seu programa deve imprimir 66 55 44 33 22

Seu programa não deve impor limitações sobre o valor de n

(63)

Referências

Documentos relacionados

O objetivo do curso foi oportunizar aos participantes, um contato direto com as plantas nativas do Cerrado para identificação de espécies com potencial

Para analisar as Componentes de Gestão foram utilizadas questões referentes à forma como o visitante considera as condições da ilha no momento da realização do

Nesse contexto, o presente trabalho tem como objetivo realizar testes de tração mecânica e de trilhamento elétrico nos dois polímeros mais utilizados na impressão

A pesquisa pode ser caracterizada como exploratória e experimental em uma primeira etapa (estudo piloto), na qual foram geradas hipóteses e um conjunto de observáveis, variáveis

de professores, contudo, os resultados encontrados dão conta de que este aspecto constitui-se em preocupação para gestores de escola e da sede da SEduc/AM, em

O Programa de Avaliação da Rede Pública de Educação Básica (Proeb), criado em 2000, em Minas Gerais, foi o primeiro programa a fornecer os subsídios necessários para que

A Procuradoria-Geral de Justiça do Ministerio Publico do Estado de Minas Gerais, por meio do Centro de Estudos e Aperfeiçoamento Funcional (CEAF), no uso das prerrogativas que lhe

Quando os dados são analisados categorizando as respostas por tempo de trabalho no SERPRO, é possível observar que os respondentes com menor tempo de trabalho concordam menos que