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を勉強したい。