Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

LucianoPeixoto_rj

Alocação Dinâmica

Recommended Posts

Bom dia pessoal,

 

Estou lendo sobre alocação dinâmica, mas ainda não entendi muito bem sua utilidade, o que eu entendi é que ao alocar dinamicamente, o algoritmo não carrega toda a memória de uma vez e sim a medida que vai sendo executado isso se torna útil quando você não sabe o limite do seu vetor. Maas, se eu souber e ele for muito grande tipo uma matriz de [500000][3] a alocação dinâmica não fazer ele rodar, ele vai travar do mesmo jeito em algum momento não é? Mesmo que eu use free depois, qual a diferença entre fazer isso (porque vou perder os dados armazenados ao faze-lo) e passar os valores para arquivo txt sobrescrevendo os valores utilizando não uma matriz, mas um vetor [3]

 

 

Abraço!

Compartilhar este post


Link para o post
Compartilhar em outros sites

 

 

mas ainda não entendi muito bem sua utilidade

Não é porque o custo do MB está baixo que vamos desperdiçar memória. Não pensar nos tipos utilizados começa a cobrar o preço quando você programa p/ ambientes limitados.

 

 

 

se eu souber e ele for muito grande tipo uma matriz de [500000][3] a alocação dinâmica não fazer ele rodar, ele vai travar do mesmo jeito em algum momento não é? Mesmo que eu use free depois, qual a diferença entre fazer isso (porque vou perder os dados armazenados ao faze-lo) e passar os valores para arquivo txt sobrescrevendo os valores utilizando não uma matriz, mas um vetor [3]

Não consegui entender nada a partir do 'não fazer ele rodar'.

Compartilhar este post


Link para o post
Compartilhar em outros sites

hahaha Vou tentar escrever melhor, espero ter conseguido

 

Matriz [5000][3] onde n interações = 5000 e cada N coluna 1,2,3 é uma grandeza como tempo, posição e velocidade para a N iteração 1, ... , 5000.

 

Segundo o que eu entendi da alocação dinâmica quando executar o programa ele não vai travar de cara porque não vai carregar a matriz inteira, porém em algum valor de Niterações ele vai travar por ter consumido ram demais, o único jeito que eu vejo de contornar isso seria usando o comando free entre cada Niteração, só que pra mim não há diferença entre fazer isso e usar um vetor [Ncolunas] que passe os valores para um txt e escreva por cima dele Nitreações vezes nas próximas repetições passando os novos para txt. Queria confirmar se o que eu entendi está correto e não tem diferença mesmo.

Compartilhar este post


Link para o post
Compartilhar em outros sites

A alocação de memória pode ser realizada em dois lugares: no heap ou no stack.
Quando vc declara int m[5000][3], vc está alocando memória no stack em tempo de compilação. Quando vc utiliza malloc/realloc (new no caso de C++), vc está alocando memória no heap em tempo de execução.

Ainda não entendi o que vc chama de "carregar a matriz inteira". À parte do local em que a memória é reservada e o gerenciamento ser automático/manual, você não carrega nada. Você reserva espaço em memória e atribui um nome a ele p/ que possa ser referenciado dentro do código. É a mesma coisa. A diferença é que você pode mexer no heap durante a execução do programa. Ex.: o programa assume que não existirão mais de 50 livros na estante no início, por isso um realloc(NULL, 50*sizeof(struct Livro)). Se o usuário quiser cadastrar mais de 50 livros, é necessário inserir um código verificador que aumente em X unidades o tamanho da estante:

 

 

if (full(....)) {
   estante = realloc(estante, (size(estante) + 10) * sizeof(struct Livro))
}

 

Você não consegue fazer isso com struct Livro estante[50].

 

Ao usar alocação dinâmica você está sujeito às seguintes situações:

1- Não há memória suficiente no heap e o malloc vai retornar NULL. Nesse caso vc deve interromper o programa e informar a causa. Se você não verificar o retorno do malloc e sair usando, em alguma situação vai dar m* já "de início".

2- Você quer aumentar a quantidade de memória alocada (sim, porque o malloc aloca um espaço físico limitado) e usa realloc. http://stackoverflow.com/questions/26072752/realloc-dangling-pointers-and-undefined-behavior
3- Você liberou memória. Não dê free de novo e nem tente usar o ponteiro de novo.

 

Gravar novos valores numa mesma área de memória não é igual a usar free.

 

http://linux.die.net/man/3/malloc

http://en.wikipedia.org/wiki/Dangling_pointer
https://www.youtube.com/watch?v=_8-ht2AKyH4

Compartilhar este post


Link para o post
Compartilhar em outros sites

Muito bom o vídeo, entendi como funciona na teoria, mas só na teoria rs Tentei aplicar no meu programa mas não está dando 100%, ele roda, mostra os resultados, mas assim que termina de mostrar ele congela na hora do comando free, o que está errado?

 

Declarei minha matriz assim: (nper e nvar são constantes)

 

 

    double **y = (double**)(malloc(nper*sizeof(double*)));    for (n=0; n<=nper; n=n+1)    {   y[n] = (double*)(malloc(nvar*sizeof(double)));    }

e liberei memória assim:

 

 

 for (n=0; n<=nper; n=n+1)    {        free (y[n]);    } free (y);

Agora sim, foi um erro bobo, ainda não me acostumei com o fato do vetor começar no 0, então quando usei o malloc saiu com o tamanho errado o que fez o código travar, agora está tudo funcionando e o comando para alocar uma matriz e liberá-la me parece ser esse mesmo.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Só algumas observações importantes:

 

1. C não define pilhas e nem heaps. A implementação pode escolher onde quer armazenar cada tipo de storage type; a discussão aqui é sobre allocated (acessível através de malloc, calloc, ...) e automatic (o que se consegue, por exemplo, dizendo char a[3] = {0};).

 

2. A conversão implícita de (T *) pra (void *) e vice-versa é bem definida; a consequência maravilhosa disso é que você pode dizer int *p = malloc(sizeof *p) ao invés de int *p = (int *) malloc(sizeof *p).

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.