我刚注意到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)
分配内存?
答案 0 :(得分:8)
GNU C库(&#34; glibc&#34;,Ubuntu上常用的C运行时)在第一次stdout
用于任何事情时为内部使用分配内存。 (对于stderr
和stdin
,它可能也是如此。)要查看这种情况,请在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)