funcao libera

funcao libera

by Rebeca Bayeh -
Number of replies: 5
Ola!
O enunciado diz que eh errado nao chamar a funcao "libera" assim que o polinomio nao tiver mais utilidade. Mas no exemplo dado, assim que o polinomio eh impresso, chama-se a funcao "libera" Mas e se a funcao for usada mais pra frente, ela tera sido descartada.

Esse exemplo foi so uma ilustracao? Se sim, entao basta liberar tudo no finzinho do cliente?

[]s
Rebeca
In reply to Rebeca Bayeh

Re: funcao libera

by Francisco Reverbel -
No primeiro dos exemplos dados no enunciado o importante é liberar o polinômio referenciado por v antes de atribuir outro polinomio a v:

 libera(v); /* libera o polinômio soma <<<<< */
 v = multiplica(p, q); /* atribui a v o polinômio produto p*q */
O polinômio anteriormente referenciado por v não tem mais utilidade, já que um novo polinômio está sendo atribuído à v. Sem a chamada a libera teríamos um "vazamento de memória", pois a memória usada por aquele polinômio não seria devolvida ao sistema.

Não basta liberar tudo no finzinho do cliente... Considere um arquivo de entrada assim:

p: 5 1 2 3 4 5 6 7 8 9 10 um polinomio qualquer
q: 1 1 0 outro polinomio
p=p+q
p=p+q
p=p+q
p=p+q
...

Se as chamadas a libera só forem feitas ao final da execução do cliente e se a sequência de atribuições p=p+q for suficientemente longa, a memória disponível para o cliente acabará... Pode demorar, mas um dia malloc devolverá NULL. Antes de consumar qualquer atribuição (como a=b+c, a=b-c, a=b*c) o cliente precisa liberar o polinômio anteriormente associado à variável atribuída!

Veja também o que acontece no segundo exemplo do enunciado:
imprime(soma(p, q), stdout);

Ninguém libera o polinômio devolvido pela função soma! Outro exemplo de "vazamento de memória"...

Um lugar onde é muito fácil esquecer de dar libera é dentro da função le_polinomio. Sugestão para todo mundo: revise a sua implementação dessa função. Durante a construção do polinomio que está sendo lido é gerada uma série de monômios e polinômios intermediários. Todos esses monômios e polinômios intermediários precisam ser liberados dentro de le_polinomio. Confiram se não faltou liberar nenhum.
In reply to Francisco Reverbel

Re: funcao libera

by Marlon Ribas Vismari -
professor, se eu alterar o exemplo do enunciado para:

libera(v); /* libera o polinômio soma <<<<< */
 v = multiplica(v, v); /* atribui a v o polinômio produto v*v */


Se eu liberar o v, multiplica fará a conta normalmente? Bom, melhor dizendo, se eu dou um free, o conteudo na memória continua lá e consigo acessar, porém se o computador precisar de memória ele vai alocar esse trecho liberado. Seria isso?
Valeu!
In reply to Marlon Ribas Vismari

Re: funcao libera

by Francisco Reverbel -
Vamos considerar o exemplo com a sua alteração:

libera(v); /* libera o polinômio soma <<<<< */
v = multiplica(v, v); /* atribui a v o polinômio produto v*v */
Desse jeito o exemplo fica errado, pois é um erro fazer acesso a memória que foi obtida via malloc e que já foi liberada via free. (Isso pode até funcionar em muitos casos, mas não há garantia que funcione, pois pode acontecer da memória liberada já ter sido alocada para outra coisa... Por isso é proibido usar essa memória depois do free!)

Note que a execução de multiplica(v, v) precisa fazer acesso ao polinômio referenciado por v, mas esse polinômio já foi liberado... O certo é liberar v depois da chamada à função multiplica e antes da próxima atribuição a v:
... /* neste ponto o polinômio referenciado por v ainda não foi liberado */
aux = multiplica(v, v); /* guarda numa variável auxiliar o produto v*v */
libera(v); /* libera o polinômio referenciado por v */
v = aux; /* atribui a v o polinômio produto v*v */

In reply to Francisco Reverbel

Re: funcao libera

by Kaonan Micadei -
No caso de uma chamda p=p+p, fazer libera(p) antes de atribuir o resultado da soma não retornaria um NULL? Não seria mais eficiente, nesse caso, usar um ponteiro temporario para p, atribuir a soma a p e então liberar o temporario (pois este guarda o endereço "original" de p)?
In reply to Kaonan Micadei

Re: funcao libera

by Francisco Reverbel -
Isso mesmo, Kaonan. Isto é equivalente ao que eu escrevi acima:
... /* neste ponto o polinômio referenciado por v ainda não foi liberado */
aux = v; /* salva numa variável auxiliar o polinomio referenciado por v */
v = multiplica(v, v); /* atualiza v com o resultado da operação (soma, produto, tanto faz...) */
libera(aux); /* libera o polinômio anteriormente referenciado por v */
Quanto ao que você disse sobre "ser mais eficiente", não é só uma questão de eficiência... Está errado usar o p depois do libera(p)!

Você parece estar supondo que a chamada libera(p) atribui NULL a p, mas para fazer isso ela precisaria receber um ponteiro para o ponteiro p... Sem receber um ponteiro para ponteiro, a função libera pode até mexer na sua cópia do ponteiro p, mas isso não terá nenhum efeito sobre o ponteiro original!