Enviar um café pro programador

Pode me ajudar a transformar cafeína em código?

O que é e para que serve a Alocação Dinâmica de memória em C

No decorrer de nossa apostila de C, frisamos várias vezes que a linguagem C costuma agir em baixo nível, ou seja, bem próximo ao hardware, na arquitetura de seu sistema.

É por isso que temos que declarar, manualmente, as variáveis, lidar com endereços de memória (ponteiros), buffer, ter cuidado para não extrapolar os limites de vetor e outros detalhes e preocupações que a maioria das linguagens não exigem do programador.

Nessa introdução, vamos explicar outra coisa que o programador C deve ter consciência: alocar somente o necessário de memória.

A alocação estática e seus problemas

Alocar estaticamente memória é o que vínhamos fazendo até então, em nossa apostila completa de C online.
No começo de nossas aplicações sempre declaramos as variáveis, bem como o tamanho de vetores.

Por exemplo, para criar uma aplicação de um banco online, precisamos que o usuário cadastre seu nome.
Quantos caracteres você deixaria disponível para que ele fizesse isso? 30? 40?
50 já seria suficiente para a maioria das pessoas...mas e se fosse um descendente da família real brasileira?

Não é incomum encontrar pessoas com 5 ou 6 sobrenomes...então sua aplicação teria uma séria falha: o usuário iria digitar mais caracteres que o permitido.

Se você alocar 10 caracteres e escrever 20, vai ver que isso é possível. Porém extremamente falho e perigoso, pois os caracteres sobressalentes irão ocupar outros endereços de memória que você não alocou, e nesses espaços de memória poderiam existir informações importantes de seu computador.
É bem comum ouvirmos falar de ataques e vírus que agem assim, nessa falha de alocação de memória e processamento.

Provavelmente já deve ter ouvido falar em 'Stack overflow', que é quando um programa usa mais memória que o que foi pré-estabelecido, ou usa mais do que é esperado.

Quanto de memória devo usar?

Vamos supor que você foi contratado por uma empresa para criar um aplicativo para gerenciar todos os funcionários.
A empresa tem 80 funcionários.

Você, como é esperto e visionário, vai criar uma struct para definir os funcionários e declarar logo 100 dessas estruturas, para armazenar os dados de seus funcionários.
Ok, sem problemas...você até garantiu espaço caso mais funcionários sejam contratados.

E se a empresa crescer demais? Passar dos 100 funcionários?
Mexer no código? Mudar pra quanto agora?

E se você decidir criar um programa de edição de textos, como o bloco de notas, quanto de memória você vai definir para uso?
1kb? Muito pouco.
1Mb? Razoável.
1Gb? Bastante, dificilmente alguém ia extrapolar isso num simples texto...
Mas há quem extrapole, e aí? Sua aplicação iria ficar limitar?

Mas 99% das pessoas só iriam usar alguns meros kb, e você iria alocar 1Gb de memória?
Que absurdo! Ia ser lento e ocupar o HD inteiro, ninguém iria usar seu programa.

Qual a solução?
Alocar o tanto que o usuário vai usar. E qual o tanto de memória que ele vai usar?
Ué, depende dele. Não é algo constante, não é estático. É dinâmico.

O que é alocação dinâmica de memória em linguagem C 

A maneira ideal de se trabalhar com memória é alocando somente o que vai se utilizar.
Óbvio, não?

Se a pessoa vai digitar 10 caracteres, armazene isso numa string de tamanho 11 (tem que ter o caractere limitador \0).
Se uma funcionária de uma farmácia vai cadastrar 20 medicamentos, seu aplicativo C deve alocar somente o espaço para as estruturas desses 20 medicamentes.

É isso que iremos aprender nessa seção do curso C Progressivo.
Sem dúvidas, é um dos tópicos mais importantes e diferenciados, pois são poucas as linguagens que vão permitir o programador ter acesso não só a memória, mas como e quanto da memória você vai usar.
Como diria o tio do Peter Parker, o Homem-Aranha: com grandes poderes, vêm grandes responsabilidades.

Como programador C, você tem total responsabilidade com o uso correto da memória.
Não use à toa, não use mais que o necessário, não gaste processamento quando não é necessário.
O diferencial da linguagem C é essa eficiência, se for para programar sem se preocupar com memória e  processamento, não faz muito sentido programar em C.

Sabendo os conceitos e uso correto da alocação dinâmica de memória, vamos selecionar somente o tanto exato de memória que vamos usar, sem desperdiçar.
Isso vai fazer com que suas aplicações C fiquem bem menores do que já são, além de não sobrecarregarem sua máquina.




Onde a alocação dinâmica é usada

Como ocorre com todos, você também irá cometer erros de programação, e errar quando estiver lidando com alocação dinâmica de memória, e isso irá trazer algumas consequências mais graves do que você está acostumado (geralmente não ocorre do jeito que você quer ou recebe um alerta do debugger) como lentidão e travamento do sistema.

Não é muito incomum vírus e aplicativos maliciosos fazerem uso excessivo de alocação de memória em seus programas maldosos.
Uma (das milhões) verificação que os anti-vírus fazem é checar quanto de memória seu sistema está usando.
Se esse número crescer muito e de forma estranha, certamente alguma aplicação está com erro ou está travando propositalmente seu sistema.

Um dos motivos da lentidão e travamentos de sistemas não muito otimizados, como Windows, é o mal gerenciamento da memória. Você abre um programa, ele aloca memória, usa, mas não libera corretamente essa memória após seu uso e usa mal durante a aplicação...então você já perde memória e processamento aí.

Depois você abre um jogo, usa absurdos de memória, que também é quase impossível de se gerenciar perfeitamente...lá vai mais memória e processamento para gerenciar essa memória...e assim vai indo, e seu sistema ficando lento, começando a travar, a demorar séculos para carregar algumas aplicações, e lá vai você gastar 50 reais para que o sobrinho da vazia venha formatar sua máquina, como se isso fosse algo normal (não, não é...experimente usar Linux).

Então, além de alocar, temos que desalocar (liberar) corretamente a memória quando não estamos mais usando.
Assim, os outros programas terão mais memória para usar.
Notou a importância da alocação dinâmica de memória em linguagem C?

12 comentários:

Manuel L. disse...

Adoro essas explicações, sempre tento falar um pouco da utilidade de cada lição de programação aos meus alunos.

Isso instiga os alunos e fazem entender o motivo de estudar aquilo.

Muito bom seu site, é bem diferente da maioria que simplesmente joga na cara do estudante os códigos sem se dar ao trabalho de explicar o quê se está fazendo e o principal, para quê.

Anônimo disse...

muito boa a introdução!

gostei do diferencial (ensinar além de como, o porque de usar).

continuem assim!

Naara disse...

Adorei esse site, além disso a qualidade de ensino é de alto nível.
Parabéns.

@guipolonca disse...

Ótimo, esse site tá me ajudando muito! Só uma pequena correção: A frase é do Tio, não do Avô do Peter Parker... xD

Maycon disse...

Acompanho vcs faz tempo, mas é a primeira vez que comento, e parabenizo pela didática extraordinária de vcs.

faço sistemas de informação pela ufpa e suas aulas são de extrema importância pro meu aprendizado. abraços e continue sempre desse jeito, ajudando o próximo. :)

Nilton Rodolfo disse...

Gosto bastante das explicações de vocês. Obrigado pela ajuda. Que Deus abençoe.

Unknown disse...

UooowwwwWW Muito Foda!

Unknown disse...

UuuooowwwWWW Muito Foda!

Anônimo disse...

E eu achando que Stack Overflow era o nome de uma rede de perguntas e respostas sobre programação da Stack Exchange... Recomendo.

Weslleyzitowsz disse...

MUITO BOM!! EXCELENTE!!

Unknown disse...

Estou estudando C++ e esse site me ajudou bastante com explicações, mesmo eu usando os comandos de C++ e nao de C

Unknown disse...

Cara, estudei alocação dinâmica na faculdade, mas nunca entendi o motivo, estou estudando novamente para concursos e mestrado e só sua explicação me fez entender os motivos. Muito obrigado, ótima explicação e trabalho.