Diferenças
Aqui você vê as diferenças entre duas revisões dessa página.
Ambos lados da revisão anterior Revisão anterior Próxima revisão | Revisão anterior | ||
pua:gerencia_de_memoria [2008/09/20 12:00] – maziero | pua:gerencia_de_memoria [2015/10/24 10:47] (atual) – maziero | ||
---|---|---|---|
Linha 1: | Linha 1: | ||
+ | ====== Gerência de memória ====== | ||
+ | |||
+ | O espaço de endereços de um processo é dividido em várias áreas distintas. As mais importantes são: | ||
+ | |||
+ | * //Text area//: contém o código do programa e suas constantes. Esta área é alocada durante a chamada '' | ||
+ | * //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, | ||
+ | * //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. | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | Um programa em 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 (// | ||
+ | * A **alocação dinâmica**, | ||
+ | |||
+ | ===== Alocação dinâmica de memória ===== | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | void * malloc (size_t size) | ||
+ | </ | ||
+ | |||
+ | Esta função aloca uma nova região com '' | ||
+ | |||
+ | <code c> | ||
+ | struct mystruct *ptr; | ||
+ | ... | ||
+ | ptr = (struct mystruct *) malloc (sizeof (struct mystruct)); | ||
+ | if (ptr == 0) abort (); | ||
+ | </ | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | void free (void *ptr) | ||
+ | </ | ||
+ | |||
+ | Esta função libera um bloco de memória previamente alocado, apontado por '' | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | void * realloc (void *ptr, size_t newsize) | ||
+ | </ | ||
+ | |||
+ | Esta função redimensiona o bloco previamente alocado apontado por '' | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | void * calloc (size_t count, size_t eltsize) | ||
+ | </ | ||
+ | |||
+ | Esta função aloca um bloco de tamanho suficiente para conter um vetor com '' | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | void * alloca (size_t size) | ||
+ | </ | ||
+ | |||
+ | Esta função provê um mecanismo de alocação dinâmica semi-automática: | ||
+ | |||
+ | Na GLibC, os blocos alocados pelas funções acima sempre iniciam em um endereço múltiplo de 8 em plataformas de 32 bits. Caso seja necessário obter blocos iniciando em múltiplos de 16, 32, 64, etc, as funções a seguir estão disponíveis: | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | void * memalign (size_t boundary, size_t size) | ||
+ | </ | ||
+ | |||
+ | Aloca um bloco de tamanho '' | ||
+ | |||
+ | ===== Arquivos mapeados em memória ===== | ||
+ | |||
+ | Sistemas operacionais modernos permitem mapear um arquivo em uma região de memória. Isso torna possível acessar o arquivo como se fosse um vetor de bytes em memória. Esse procedimento é mais eficiente que os tradicionais '' | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | void * mmap (void *address, size_t length,int protect, int flags, int filedes, off_t offset) | ||
+ | </ | ||
+ | |||
+ | Cria um novo mapeamento em memória relacionado aos bytes '' | ||
+ | |||
+ | O campo '' | ||
+ | |||
+ | O campo '' | ||
+ | |||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | Deve-se observar que nem todos os descritores de arquivo podem ser mapeados em memória. Normalmente, | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | int munmap (void *addr, size_t length) | ||
+ | </ | ||
+ | |||
+ | Remove mapeamentos efetuados entre ('' | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | #include < | ||
+ | int msync (void *address, size_t length, int flags) | ||
+ | </ | ||
+ | |||
+ | Permite sincronizar um mapeamento de arquivo em memória com a imagem do arquivo em disco. | ||
+ | |||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | ===== Proteção de páginas em memória ===== | ||
+ | |||
+ | É possível informar ao sistema operacional que certas páginas de memória virtual nunca devem ser enviadas para o disco (// | ||
+ | |||
+ | * // | ||
+ | * // | ||
+ | |||
+ | Por causa de seus possíveis efeitos sobre outros processos (reduzindo a disponibilidade de memória do sistema), normalmente só processos do administrador podem travar páginas em memória (mais detalhes na página de manual de '' | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | int mlock (const void *addr, size_t len) | ||
+ | </ | ||
+ | |||
+ | Permite travar na memória um conjunto de páginas do processo. A faixa de memória a travar inicia em '' | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | int munlock (const void *addr, size_t len) | ||
+ | </ | ||
+ | |||
+ | Faz o inverso de '' | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | int mlockall (int flags) | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | int munlockall (void) | ||
+ | </ | ||
+ | |||
+ | Faz o contrário de '' | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | int mprotect(const void *addr, size_t len, int prot); | ||
+ | </ | ||
+ | |||
+ | Controla a forma como uma região de memória pode ser acessada. Caso a forma de acesso definida seja violada, o processo recebe um sinal '' | ||
+ | |||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | ===== Operações em blocos de memória ===== | ||
+ | |||
+ | As funções aqui indicadas são úteis para operar com blocos de memória alocados estatica ou dinamicamente. | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | void * memcpy (void *restrict to, const void *restrict from, size_t size) | ||
+ | </ | ||
+ | |||
+ | Copia '' | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | void * memmove (void *to, const void *from, size_t size) | ||
+ | </ | ||
+ | |||
+ | Copia '' | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | void * memccpy (void *restrict to, const void *restrict from, int test, size_t size) | ||
+ | </ | ||
+ | |||
+ | Copia até '' | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | void * memset (void *addr, int value, size_t size) | ||
+ | </ | ||
+ | |||
+ | Copia o valor de '' | ||
+ | |||
+ | ===== Depurando problemas de memória ===== | ||
+ | |||
+ | As operações envolvendo ponteiros e alocação dinâmica de memória costumam levar a bugs complexos e muitas vezes difíceis de resolver. Existem várias ferramentas para auxiliar o programador a localizar e resolver problemas relacionados à alocação dinâmica de memória e uso inadequado de ponteiros em C/C++: | ||
+ | |||
+ | * [[http:// | ||
+ | * [[http:// | ||
+ | * [[http:// | ||
+ | * [[http:// | ||
+ | * [[http:// | ||
+ | * [[http:// | ||
+ | * [[http:// | ||
+ | |||
+ | ===== Atividades ===== | ||
+ | |||
+ | A definir... | ||