Commit dbb66775 authored by Davisson Henrique Paulino's avatar Davisson Henrique Paulino

Merge branch 'master' into ponteiros

parents ca235b27 8076ba4f
......@@ -43,9 +43,7 @@ em que o programa ficou em execução. Como o tamanho dos segmentos é fixo (da
estática), esses 2 Mb de memória alocados estaticamente estariam reservados para o programa, mas não
seriam utilizados (um exemplo de programa mal-comportado).
Ou seja, o programa estaria retendo 2 Mb de memória que poderiam ser usados por outros programas
e essa memória alocada, mas não utilizada, pode trazer problemas, como impedir que se possa executar
outros programas por falta de memória.
Ou seja, o programa estaria retendo 2 Mb de memória que poderiam ser usados por outros programas, podendo impedir a execução dos mesmos por falta de memória.
Poderia ser argumentado que pelo menos o programa funciona. Agora suponha que aquele arquivo
tivesse seu tamanho aumentado para 2.5 Mb. Seria necessáro alterar no código o tamanho da matriz e
......@@ -57,7 +55,7 @@ liberados para outros programas quando deixassem de ser úteis.
É aí que entra a alocação dinâmica: a alocação dinâmica permite que o programa reserve uma área
de memória de qualquer tamanho (dentro dos limites do tamanho da memória, é claro) em tempo de
execução. Isso quer dizer que o programa/programador/compilador não precisa saber antecipadamente
o tamanho do bloco de memória de que o nosso programa precisa.
o tamanho do bloco de memória de que o programa precisa.
Durante a execução, o programa descobre qual é o tamanho da área de memória que necessita e pede
ao sistema operacional para reservar uma área de memória daquele tamanho. O sistema operacional
......@@ -70,7 +68,7 @@ de memória alocada. No programa, esse endereço pode ser armazenado em um ponte
Antes de apresentar as funções de manipulação de memória dinâmica, é importante descrever o operador
sizeof.
O operador sizeof é usado para obter o tamanho, em bytes, de um determinado tipo de dado.
O operador sizeof(sim, é um operador) é retorna o tamanho, em bytes, de um determinado tipo de dado ou variável.
A sintaxe geral é:
\begin{lstlisting}
......@@ -78,20 +76,19 @@ sizeof(tipo) // ou ainda
sizeof(variavel)
\end{lstlisting}
O sizeof retorna o tamanho do tipo passado como parâmetro ou do tipo da variável passada como
parâmetro.
Exemplos:
Veja os Exemplos:
\begin{lstlisting}
struct coord {
int x, y, z;
int x; //4 bytes
char y; // 1 bytes
char z[3]; //3 bytes
};
struct coord coordenada1;
struct coord coord_var;
sizeof(struct coord); // obtêm o valor 12 (4 bytes por int )
sizeof(coordenada1); // obtêm o valor 12 (4 bytes por int )
sizeof(struct coord); // obtêm o valor 8 (4 bytes por int + 1 por char + 3 pelo array de chars)
sizeof(coord_var); // obtêm o valor 8 (4 bytes por int + 1 por char + 3 pelo array de chars)
sizeof(int); // obtêm o valor 4
\end{lstlisting}
......@@ -103,7 +100,7 @@ tipo de dado.
A função malloc requisita ao sistema operacional para alocar uma área de memória do tamanho especificado.
Essa função é extremamente útil para gerar matrizes cujo tamanho não é possível ser definido antes
de executar o programa. Além disso, existem estruturas de dados (listas, filas, pilhas, entre outras) que
de executar o programa. Além disso, existem diversas estruturas de dados (listas, filas, pilhas, entre outras) que
tem tamanho variável e precisam dessa função para serem implementadas.
O protótipo da função malloc é:
......@@ -135,15 +132,21 @@ int main(){
printf("Digite o tamanho do vetor:");
scanf("%d", &tamanho);
vetor = (int*)malloc(sizeof(int)*tamanho);
vetor = malloc(sizeof(int)*tamanho);
return 0;
}
\end{lstlisting}
Observe que para alocar o tamanho correto para um vetor de int, é necessário multiplicar o número
de células que se deseja pelo tamanho do tipo de dado int porque cada célula individual é do tamanho
int.
de células que se deseja pelo tamanho do tipo de dado int, pois cada célula é do tamanho de um
inteiro.
\subsection{Não faça casting}
É muito comum vermos em exemplos de código utilizando a função malloc o \textit{casting} do retorno da função, pois em versões antigas de C (pre ANSI C), o retorno do malloc era um \textit{char *}, o que justificava o casting. Entretanto, este comportamento foi alterado e o retorno é um \textit{void *}. Mas então, por que realizar um \textit{casting}?
Primeiro, é desenecessário realizar esta conversão, sendo que ela é feita automaticamente. Mas principalmente, ao realizar o \textit{casting} explícito, você pode estar ocultando algum erro, como esquecer de incluir a biblioteca <stdlib.h>.
\section{Função free()}
......@@ -158,6 +161,19 @@ void free (void *memblock);
A função recebe um único argumento, o qual é um ponteiro para uma área de memória previamente
alocada com malloc.
\section{Função realloc()}
A função realloc serve para realocar um espaço de memória previamente alocado, podendo aumentar ou dimuir este espaço.
O protótipo da função realloc é:
\begin{lstlisting}
void *realloc(void *ptr, size_t size)
\end{lstlisting}
A função recebe dois parâmetros. O primeiro é um apontador para o endereço da memória que será realocado e o segundo é o tamanho do espaço desejado.
\vspace*{\fill}
\textit{Este espaço foi propositalmente deixado em branco. Veja o código completo na próxima página.}
......@@ -168,12 +184,12 @@ alocada com malloc.
\section{Exercícios}
1) Faça uma função gera matriz com os seguintes parâmetros:
1) Faça uma função gera uma matriz com os seguintes parâmetros:
\begin{lstlisting}
int*** geramatriz(int x, int y, int z, int tam);
\end{lstlisting}
A função deverá alocar uma matriz de dimensão 3, cada dimensão deverá ter tamanho tam e, ao final,
A função deverá alocar uma matriz de dimensão 3, cada dimensão deverá ter tamanho "tam" e, ao final,
a função retorna a matriz.
2) Crie uma função que seja capaz de redimensionar um vetor previamente alocado (vetor de dimensão
......@@ -182,13 +198,13 @@ a função retorna a matriz.
A função será chamada realoca e receberá os seguintes parâmetros:
\begin{lstlisting}
int* realoca(int *vetor, int tam, int novo tam);
int* realoca(int *vetor, int tam, int novo_tam);
\end{lstlisting}
Onde vetor é o vetor que deve ser realocado, tam é o tamanho velho do vetor e novo tam é o novo
Onde "vetor" é o vetor que deve ser realocado, "tam" é o tamanho velho do vetor e "novo\_tam" é o novo
tamanho.
A função deverá ser capaz de preservar o conteúdo de vetor. Se o novo tam for menor que tam, a
A função deverá ser capaz de preservar o conteúdo de vetor. Se o novo tamanho for menor que o antigo, a
informação das células excedentes deve ser descartada.
\end{document}
\end{document}
\ No newline at end of file
// calcula a media de n notas especificadas pelo usuario
// calcula a media de n notas especificadas pelo usuario
#include <stdlib.h>
#include <stdio.h>
......@@ -7,25 +7,25 @@ int main() {
int i, n;
printf ("Digite o numero de notas: ");
scanf ("%d", &n); // obtem o numero de notas
scanf ("%d", &n); // obtem o numero de notas
if (n < 1) { // verifica se o numero e valido
if (n < 1) { // verifica se o numero e valido
printf ("Numero invalido! Deve ser maior que zero.\n");
return;
}
// aloca memoria
notas = (double*) malloc (n * sizeof(double));
// aloca memoria
notas = malloc (n * sizeof(double));
for (i = 0; i < n; i++) { // obtem as notas
for (i = 0; i < n; i++) { // obtem as notas
printf ("Digite a %da. nota: ", i+1);
scanf ("%lf", (notas+i));
}
// calcula a media das notas
// calcula a media das notas
for (i = 0; i < n; i++)
media += *(notas+i);
media /= n;
printf ("A media das notas e: %f\n", media);
free (notas); // desaloca a memoria alocada previamente
free (notas); // desaloca a memoria alocada previamente
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment