Valgrind:stdio.h的函数“puts”分配内存

时间:2016-07-02 23:00:18

标签: c valgrind

我刚注意到valgrind显示此代码分配了内存:

javac -cp kneipe kneipe/location/Show.java

使用#include <stdio.h> int main(void) { puts("Hello world"); } 编译时的结果:

gcc (Ubuntu 5.3.1-14ubuntu2.1)

为什么它显示==25080== Memcheck, a memory error detector ==25080== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. ==25080== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info ==25080== Command: ./a.out ==25080== Hello world ==25080== ==25080== HEAP SUMMARY: ==25080== in use at exit: 0 bytes in 0 blocks ==25080== total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated ==25080== ==25080== All heap blocks were freed -- no leaks are possible ==25080== ==25080== For counts of detected and suppressed errors, rerun with: -v ==25080== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) 分配内存?

2 个答案:

答案 0 :(得分:8)

GNU C库(&#34; glibc&#34;,Ubuntu上常用的C运行时)在第一次stdout用于任何事情时为内部使用分配内存。 (对于stderrstdin,它可能也是如此。)要查看这种情况,请在gdb下运行您的程序,并在达到main后,在{{上设置断点1}}和brk,它们是最终用于分配内存的系统调用。然后继续。

mmap

您可以看到调用堆栈经过一堆内部内容,最终到达Reading symbols from ./a.out...done. (gdb) b main Breakpoint 1 at 0x4004ea: file test.c, line 5. (gdb) r Starting program: /home/zack/a.out Breakpoint 1, main () at test.c:5 5 puts("Hello world"); (gdb) b brk Breakpoint 2 at 0x7ffff7b183c0: file ../sysdeps/unix/sysv/linux/x86_64/brk.c, line 31. (gdb) b mmap Breakpoint 3 at 0x7ffff7b1bc00: file ../sysdeps/unix/syscall-template.S, line 84. (gdb) c Continuing. Breakpoint 3, mmap64 () at ../sysdeps/unix/syscall-template.S:84 84 ../sysdeps/unix/syscall-template.S: No such file or directory. (gdb) bt #0 mmap64 () at ../sysdeps/unix/syscall-template.S:84 #1 0x00007ffff7a9f49c in __GI__IO_file_doallocate ( fp=0x7ffff7dd6620 <_IO_2_1_stdout_>) at filedoalloc.c:128 #2 0x00007ffff7aac550 in __GI__IO_doallocbuf ( fp=fp@entry=0x7ffff7dd6620 <_IO_2_1_stdout_>) at genops.c:418 #3 0x00007ffff7aab9d8 in _IO_new_file_overflow ( f=0x7ffff7dd6620 <_IO_2_1_stdout_>, ch=-1) at fileops.c:820 #4 0x00007ffff7aaab8a in _IO_new_file_xsputn ( f=0x7ffff7dd6620 <_IO_2_1_stdout_>, data=0x400584, n=11) at fileops.c:1331 #5 0x00007ffff7aa18d8 in _IO_puts (str=0x400584 "Hello world") at ioputs.c:41 #6 0x00000000004004f4 in main () at test.c:5

也许您想知道为什么库会这样做。原因在Chuck Walbourn的回答中暗示:内存将用于缓冲输出,并且在第一次使用puts之前不会分配,因为有些程序从不使用{ {1}}他们并不想浪费记忆。 (这个设计决定可能在20年前更有意义。)

答案 1 :(得分:1)

默认情况下,标准允许标准输出stdout进行缓冲。您可以使用setvbuf更改此内容。