I've been thinking of what will happen if I assign a longer string literal to a char array of smaller size. (I understand that if I use a string literal as an initializer, I would probably leave out the size and let the compiler count the number of chars, or use strlen()+1 as the size. )
I have the following code:
#include <stdio.h>
int main() {
char a[3] = "abc"; // a[2] gives an error of initializer-string for array of chars is too long
printf("%s\n", a);
printf("%p\n", a);
}
I expect it to crash but it actually compiles without warning and can print things out. But using valgrind, I get the following error messages.
==19195== Memcheck, a memory error detector
==19195== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==19195== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==19195== Command: ./a.out
==19195==
==19195== Conditional jump or move depends on uninitialised value(s)
==19195== at 0x4E88CC0: vfprintf (vfprintf.c:1632)
==19195== by 0x4E8F898: printf (printf.c:33)
==19195== by 0x4005CC: main (main.c:5)
==19195==
==19195== Conditional jump or move depends on uninitialised value(s)
==19195== at 0x4EB475D: _IO_file_overflow@@GLIBC_2.2.5 (fileops.c:850)
==19195== by 0x4EB56AF: _IO_default_xsputn (genops.c:455)
==19195== by 0x4EB32C6: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1352)
==19195== by 0x4E8850A: vfprintf (vfprintf.c:1632)
==19195== by 0x4E8F898: printf (printf.c:33)
==19195== by 0x4005CC: main (main.c:5)
==19195==
==19195== Conditional jump or move depends on uninitialised value(s)
==19195== at 0x4EB478A: _IO_file_overflow@@GLIBC_2.2.5 (fileops.c:858)
==19195== by 0x4EB56AF: _IO_default_xsputn (genops.c:455)
==19195== by 0x4EB32C6: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1352)
==19195== by 0x4E8850A: vfprintf (vfprintf.c:1632)
==19195== by 0x4E8F898: printf (printf.c:33)
==19195== by 0x4005CC: main (main.c:5)
==19195==
==19195== Conditional jump or move depends on uninitialised value(s)
==19195== at 0x4EB56B3: _IO_default_xsputn (genops.c:455)
==19195== by 0x4EB32C6: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1352)
==19195== by 0x4E8850A: vfprintf (vfprintf.c:1632)
==19195== by 0x4E8F898: printf (printf.c:33)
==19195== by 0x4005CC: main (main.c:5)
==19195==
==19195== Syscall param write(buf) points to uninitialised byte(s)
==19195== at 0x4F306E0: __write_nocancel (syscall-template.S:84)
==19195== by 0x4EB2BFE: _IO_file_write@@GLIBC_2.2.5 (fileops.c:1263)
==19195== by 0x4EB4408: new_do_write (fileops.c:518)
==19195== by 0x4EB4408: _IO_do_write@@GLIBC_2.2.5 (fileops.c:494)
==19195== by 0x4EB347C: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1331)
==19195== by 0x4E8792C: vfprintf (vfprintf.c:1663)
==19195== by 0x4E8F898: printf (printf.c:33)
==19195== by 0x4005CC: main (main.c:5)
==19195== Address 0x5203043 is 3 bytes inside a block of size 1,024 alloc'd
==19195== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==19195== by 0x4EA71D4: _IO_file_doallocate (filedoalloc.c:127)
==19195== by 0x4EB5593: _IO_doallocbuf (genops.c:398)
==19195== by 0x4EB48F7: _IO_file_overflow@@GLIBC_2.2.5 (fileops.c:820)
==19195== by 0x4EB328C: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1331)
==19195== by 0x4E8850A: vfprintf (vfprintf.c:1632)
==19195== by 0x4E8F898: printf (printf.c:33)
==19195== by 0x4005CC: main (main.c:5)
==19195==
abc?
0xfff0003f0
==19195==
==19195== HEAP SUMMARY:
==19195== in use at exit: 0 bytes in 0 blocks
==19195== total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
==19195==
==19195== All heap blocks were freed -- no leaks are possible
==19195==
==19195== For counts of detected and suppressed errors, rerun with: -v
==19195== Use --track-origins=yes to see where uninitialised values come from
==19195== ERROR SUMMARY: 10 errors from 5 contexts (suppressed: 0 from 0)
I think the uninitialized value/byte part makes sense because there's no memory allocated for the terminating character '\0', and when I print it out the last char is garbage value.
But the last error message looks unfamiliar to me.
Address 0x5203043 is 3 bytes inside a block of size 1,024 alloc'd
I'm aware that the buffer size is defined as 1024. I'm not sure if this error is here because of inefficient use of memory.
Also I'm wondering where does the heap alloc and free come from? Is that from the string literal?
Thanks for any help!!
(The previous subject of this question might be confusingly worded. I changed it. )