printfで文字列のところにintを渡す
#include <stdio.h> int main(int argc, char *argv[]) { int i = 100; printf("%s:\n", i); return 0; }
とするとSEGVで落ちるけど、このとき起こっていることを理解してなかったと、久しぶりに使った valgrind のメッセージで気付いた。
$ valgrind ./seg ==25237== Memcheck, a memory error detector ==25237== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al. ==25237== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info ==25237== Command: ./seg ==25237== ==25237== Invalid read of size 1 ==25237== at 0xC884: strlen (mc_replace_strmem.c:398) ==25237== by 0x1728C2: __vfprintf (in /usr/lib/system/libsystem_c.dylib) ==25237== by 0x17118D: vfprintf_l (in /usr/lib/system/libsystem_c.dylib) ==25237== by 0x17A2CF: printf (in /usr/lib/system/libsystem_c.dylib) ==25237== by 0x100000F12: main (seg.c:6) ==25237== Address 0x64 is not stack'd, malloc'd or (recently) free'd ==25237== ==25237== ==25237== Process terminating with default action of signal 11 (SIGSEGV) ==25237== Access not within mapped region at address 0x64 ==25237== at 0xC884: strlen (mc_replace_strmem.c:398) ==25237== by 0x1728C2: __vfprintf (in /usr/lib/system/libsystem_c.dylib) ==25237== by 0x17118D: vfprintf_l (in /usr/lib/system/libsystem_c.dylib) ==25237== by 0x17A2CF: printf (in /usr/lib/system/libsystem_c.dylib) ==25237== by 0x100000F12: main (seg.c:6) ==25237== If you believe this happened as a result of a stack ==25237== overflow in your program's main thread (unlikely but ==25237== possible), you can try to increase the size of the ==25237== main thread stack using the --main-stacksize= flag. ==25237== The main thread stack size used in this run was 8388608. ==25237== ==25237== HEAP SUMMARY: ==25237== in use at exit: 6,316 bytes in 33 blocks ==25237== total heap usage: 33 allocs, 0 frees, 6,316 bytes allocated ==25237== ==25237== LEAK SUMMARY: ==25237== definitely lost: 0 bytes in 0 blocks ==25237== indirectly lost: 0 bytes in 0 blocks ==25237== possibly lost: 0 bytes in 0 blocks ==25237== still reachable: 6,316 bytes in 33 blocks ==25237== suppressed: 0 bytes in 0 blocks ==25237== Rerun with --leak-check=full to see details of leaked memory ==25237== ==25237== For counts of detected and suppressed errors, rerun with: -v ==25237== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 1 from 1) zsh: segmentation fault valgrind ./seg
「Access not within mapped region at address 0x64」というのは、つまりメモリアドレスの100のところに文字列を読みに行ったってことか。コンパイラは型の不一致について警告を出すけど、実行自体は愚直というか何も複雑なことをしないのね。生っぽい。うーん、もう少しCを勉強したい。