paulo1205
(usa Ubuntu)
Enviado em 21/06/2017 - 08:29h
O fato de o ponteiro que aponta para a área ser estático não faz com que a área apontada se comporte como memória estática.
Veja este exemplo, ligeiramente diferente do seu.
#include <stdlib.h>
#include <stdio.h>
void f(void){
static char *buf;
buf=calloc(4096, 4096); // Aloca 16MiB
printf("%p\n", buf);
}
int main(void){
for(int i=0; i<10; ++i){
printf("%d: ", i);
f();
}
}
Dá para ver que há vazamento de memória, pois o ponteiro vai apontando cada vez para posições diferentes.
No seu caso, porém, você realoca a mesma região de memória, e interrompe o programa se a realocação falhar. Esse fato de matar o programa em caso de falha na realocação é crucial para não haver vazamento. O seu ponteiro, a qualquer momento da execução do programa, vai ser ou nulo ou vai apontar para uma região bem definida, alocada ou realocada sucessivas vezes, sem provocar vazamentos.
Contudo, o valgrind não faz uma análise semântica do seu programa, mas, grosso modo, se limita a ver se aquilo que foi alocado durante a vida do programa é efetivamente desalocado antes de o programa terminar.
Se você quiser calar o valgrind (e, no fundo, se desfazer da engenhosidade do seu esquema), poderia transformar seu ponteiro em global (ou com escopo de arquivo), e criar uma função de desalocação, que você poderia registrar com
atexit (). Contudo, para que essa estratégia de calar funcionasse mesmo, você teria de mudar um pouco o modo de chamar
realloc (), deixando-o mais canônico, a fim de evitar a perda de referência à região alocada caso a realocação falhasse (caso em que
realloc () devolveria o valor
NULL ).
#include <stdlib.h>
#include <stdio.h>
static char *buf; // buf com escopo de arquivo (não visível por outros módulos).
void cleanbuf(void){
free(buf);
}
void f(void){
static size_t size=1048576;
void *ptr_aux;
ptr_aux=realloc(buf, size*=2);
if(!ptr_aux)
exit(1);
buf=ptr_aux;
printf("%p\n", buf);
}
int main(void){
atexit(cleanbuf);
for(int i=0; i<10; ++i){
printf("%d: ", i);
f();
}
}