简体   繁体   中英

C function fscanf with memory loss

I am currently using function fscanf to parse a file with some char and float point. I confirmed the results by printing them out and memory check with valgrind . Now, the printing is correct but there are always a definitely loss of memory.

This is a sample code:

FILE* table;
table = fopen("table", "r");
double mass;
while (fscanf(table, %lf ", &mass) != EOF){
    printf("mass: %lf\n", mass);
}

and the valgrind with --leak-check=full option says:

==7104== 513 bytes in 1 blocks are definitely lost in loss record 52 of 62
==7104==    at 0x100008EBB: malloc (in /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==7104==    by 0x1001EF66C: __parsefloat_buf (in /usr/lib/system/libsystem_c.dylib)
==7104==    by 0x1001ED9EF: __svfscanf_l (in /usr/lib/system/libsystem_c.dylib)
==7104==    by 0x1001E1492: fscanf (in /usr/lib/system/libsystem_c.dylib)
==7104==    by 0x100000F3F: main (in ./prtm)

I think it's the problem of format. I've also tried to use %f and float but just get more similar error. Can anyone tell me what goes wrong?

Although you do not fclose() to file in the code fragment posted, I doubt this is causing trouble. In any case, make sure you fclose() the file.

The function fscanf seems to allocate memory for its own purposes and does not free it at program exit. valgrind usually knows about such unavoidable memory leak and suppresses the output, for for some reason it missed this one.

This message does not seem to indicate a problem in your code. The reported lost block is allocated by the OS/X version of fscanf() as can be seen from the call stack, for its internal floating point parser __parsefloat_buf .

More precisely, the source code to the LibC is available from http://opensource.apple.com ( Libc-763.11/stdio/vfscanf-fbsd.c:965 ) and the block should have been free'd upon exit.

You could try and free it yourself with this, but I do not recommend adding this fragment to production code.

#include <stdlib.h>
#include <pthread.h>
#include <sys/cdefs.h>

...

free(pthread_getspecific(__LIBC_PTHREAD_KEY_PARSEFLOAT));
pthread_setspecific(__LIBC_PTHREAD_KEY_PARSEFLOAT, NULL);

Instead, as pointed out by Rad Lexus, you should tell valgrind to ignore this warning as shown in this question: On OSX Valgrind reports this memory leak, Where is it coming from?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM