Olá, seja bem-vindo de volta. Nesta palestra, quero falar sobre alocação dinâmica de memória.
Isso está diretamente relacionado a ponteiros, você só pode empregar isso
em ponteiros. Então vamos começar.
Portanto, sempre que você define uma variável
em c, o compilador aloca automaticamente a quantidade correta de armazenamento para você com base no tipo de dados.
Nós vimos isso por toda parte. Quando criamos inteiros, flutuantes, duplos, não precisamos alocar memória.
O compilador faz isso por você. Na verdade, ele aloca alguma memória.
A propósito, o mesmo vale para os ponteiros. Quando você cria um ponteiro, a memória é
alocada para você, de modo que ele armazena um tipo de ponteiro, um endereço.
Agora, isso não significa que a memória foi alocada para esse endereço.
Até este ponto, sempre que atribuímos dados a um -
a um ponteiro, sempre atribuímos uma variável existente.
Portanto, se quisermos atribuir dados
a um ponteiro, usamos o endereço do e comercial do operador
em uma variável que já tinha memória alocada para ela.
Mas e se você quisesse criar um ponteiro e não quisesse atribuir a ele o
endereço do operador, você quisesse alocar memória dinamicamente. É disso que trata toda esta palestra.
Portanto, é frequentemente desejável ser capaz de alocar armazenamento dinamicamente enquanto um
programa está sendo executado. Aloque memória conforme necessário.
Se você tiver um programa projetado para ler um conjunto de dados de
um arquivo em uma matriz na memória, terá três opções.
Você pode definir a matriz para conter o número máximo de elementos possíveis que compilar o
tempo, é um tamanho fixo.
Se você definir a matriz com 50 elementos,
ela conterá apenas 50 elementos. O compilador determina que é 50, ele
vai alocar essa quantidade de memória quando for executado.
Você pode usar uma matriz de comprimento variável para dimensionar o tamanho do tempo de execução da matriz.
Falamos um pouco sobre esses arrays de comprimento
variável, eles não são suportados até C11. Na verdade, eles estão removendo o C11, eles estão adicionando o C99.
É aqui que você pode inserir variáveis.
Mas eles ainda têm tamanho fixo porque tudo
o que isso significa arrays vinculados a variáveis é que você pode passar variáveis para tamanhos.
Mas eles ainda estão estáticos.
Ou a melhor opção é alocar o array dinamicamente conforme necessário.
E há diferentes funções c que você pode chamar para fazer isso.
Portanto, será muito útil poder alocar memória dinamicamente.
Portanto, com a primeira abordagem que temos feito até agora, seja um array
ou um tipo de dados, é um tamanho fixo.
Você tem que definir seu array para conter o número máximo de elementos
que estarão certos em um array.
Então você faria algo assim, int dataArray [1000].
O que isso significa é que o arquivo de dados não pode conter mais de mil elementos.
Se isso acontecer, seu programa será interrompido.
Portanto, você só precisa esperar que o arquivo em que está lendo não tenha muitos dados.
Seu programa não funcionará com grandes conjuntos de arquivos ou arquivos grandes.
E se você quiser trabalhar com arquivos grandes, terá que voltar atrás e aumentar o array.
Você tem que mudar o tamanho,
mas então você tem que recompilar em todas aquelas coisas, é tempo de compilação.
Não importa o valor selecionado, você sempre tem a chance de
se deparar com o mesmo problema novamente no futuro, porque é um tamanho fixo.
Este tamanho é determinado quando você compila o código,
ele não se ajusta quando você executa o programa.
Não muda dinamicamente.
Usando funções de alocação de memória dinâmica, você pode obter armazenamento conforme necessário.
Essa abordagem permite alocar memória durante a execução do programa.
Então pense nas vantagens disso. Em primeiro lugar, você
não cria uma tonelada de memória que
não possa usar, você só criará o quanto precisar.
E se precisar de mais, você pode alocar mais.
Você não precisa voltar e recompilar e alterar o tamanho.
Portanto, a alocação de memória dinâmica é o caminho a percorrer.
Depende do conceito de ponteiro e fornece
um forte incentivo para usar ponteiros em seu código.
Então falamos sobre as vantagens dos ponteiros e
você deve ter pensado bem, ok, eles são um conceito legal, mas por
que precisamos usá-los, este
é um dos grandes motivos, para que você possa alocar memória dinamicamente.
E, novamente, o que é isso - C tem tudo a ver com ser uma linguagem eficiente
e não usar uma tonelada de memória.
Então c é executado em sistemas embarcados, programação em tempo real e
esta é uma das razões porque você pode limitar a quantidade de memória que
você usa com base na necessidade.
Portanto, a alocação de memória dinâmica permite que a memória para armazenar dados seja alocada dinamicamente quando
o programa é executado.
Alocar memória dinamicamente só é possível porque
você tem ponteiros disponíveis.
Como você tem um endereço e
pode alterar para onde o ponteiro está apontando, você pode reajustar a memória.
A maioria dos programas de produção usará alocação dinâmica de memória.
Se você está escrevendo código em c, você vai usar isso.
Mesmo se você for um iniciante, você usará
a alocação de memória dinâmica. A maioria dos programas úteis empregará esse conceito.
Alocar dados dinamicamente permite que você crie ponteiros em tempo de execução que são grandes o
suficiente para conter a quantidade de dados de que você precisa para a tarefa, de
forma que você não esteja desperdiçando memória. Vital.
Também precisamos falar sobre heap versus pilha.
Existem duas maneiras de armazenar memória em um programa, duas estruturas
de dados diferentes nas quais você pode armazenar dados na pilha ou pode armazenar
dados no heap.
A alocação de memória dinâmica reserva tudo no heap.
Não vamos entrar em detalhes sobre como eles são organizados, mas essencialmente.
Quando você armazena dados no heap, isso permite
mais alterações.
Você pode alterar arbitrariamente o tamanho dos objetos de dados e ele permanece por
muito mais tempo quando você aloca memória em um heap,
ele permanece em todo o seu programa.
Quando você usa uma pilha, é mais limitante.
A pilha é usada para tudo, desde argumentos de função e variáveis locais.
É onde tudo isso é armazenado.
E é por isso que falamos sobre a pilha de chamadas.
Ele examinou métodos
e funções. Eu uso métodos de vez em quando, mas métodos é realmente um termo
orientado a objeto, portanto, funções.
Tudo relacionado a funções é criado na pilha.
Isso significa que, quando você executa uma
função, ela é colocada na pilha. As variáveis locais são colocadas na pilha.
Quando você sai da função, tudo é excluído.
Portanto, a memória localizada na pilha não dura muito tempo.
Essa é uma das razões pelas quais quando você aloca dinamicamente
a memória, ela
está no heap, porque você controla quando a usa e quando não a usa, você a aloca e apaga.
Coisas na pilha, você não controla. Ele é excluído
automaticamente, é alocado automaticamente.
Portanto, as variáveis locais, as variáveis dentro de funções como a principal,
são criadas na pilha e assim por diante.
A memória no heap é diferente, é controlada por você, o programador.
Quando você aloca memória no heap, depende de você controlar quando a memória
alocada não é mais necessária, portanto, é necessário excluí-la.
Você tem que liberar o espaço
quando ele não for mais usado por você. E isso é importante
porque a memória é um recurso muito, muito escasso.
Hoje temos muita memória que dá para rodar um computador, 12 GB, 16
GB seja o que for. Mas, para programas
integrados em execução em dispositivos, você não
tem necessariamente tanta memória. E então você deseja controlar a quantidade
de memória usada e também deseja liberar a memória quando terminar de usá-la
para que outros aplicativos possam usá-la.
Novamente, mais importante em sistemas de tipo embutido de baixo nível.
Mas essa é uma liberdade que muitos idiomas não têm. Essa capacidade de controlar
a memória do gerente pelo programador, e pode tornar o
programa muito mais eficiente e muito mais rápido.
Então, na próxima aula, vamos falar sobre como você pode realmente
fazer isso, quais funções você pode invocar. Obviamente, existem diferentes funções que você pode
chamar para alocar memória para liberar memória. Obrigada.