Прежде всего, это неопределенное поведение, поэтому может произойти все что угодно;Как сказано в комментарии, на моей машине я получаю точно такое же поведение с отключенной оптимизацией, но, включив оптимизацию, я получаю предупреждение о потенциальном переполнении буфера во время компиляции (впечатляющая работа gcc!) и большойсбой во время выполнения.Еще лучше, если я напечатаю его с puts
перед printf
вызовами, я напечатаю его с другим номером a
.
Тем не менее, у меня есть сомнительная удача получить Точное такое же поведение, как и у вас, поэтому давайте разберемся.Я скомпилировал вашу программу без оптимизации и отладочной информации
[matteo@teokubuntu ~/scratch]$ gcc -g memset_test.c
, затем запустил отладчик и добавил точку останова на первом printf
сразу после memset
.
Reading symbols from a.out...done.
(gdb) break 20
Breakpoint 1 at 0x87e: file memset_test.c, line 20.
(gdb) r
Starting program: /home/matteo/scratch/a.out
Breakpoint 1, main () at memset_test.c:20
20 printf("sizeof(char) ------ %ld\n", sizeof(char));
теперь мы можем установить аппаратную точку останова записи в 26-й ячейке памяти, на которую указывает charptr
(gdb) p charptr
$1 = 0x555555756260 'a' <repeats 100 times>
(gdb) watch charptr[26]
Hardware watchpoint 2: charptr[26]
... и так ...
(gdb) c
Continuing.
Hardware watchpoint 2: charptr[26]
Old value = 97 'a'
New value = 0 '\000'
_int_malloc (av=av@entry=0x7ffff7dcfc40 <main_arena>, bytes=bytes@entry=1024) at malloc.c:4100
4100 malloc.c: File o directory non esistente.
(gdb) bt
#0 _int_malloc (av=av@entry=0x7ffff7dcfc40 <main_arena>, bytes=bytes@entry=1024) at malloc.c:4100
#1 0x00007ffff7a7b0fc in __GI___libc_malloc (bytes=1024) at malloc.c:3057
#2 0x00007ffff7a6218c in __GI__IO_file_doallocate (fp=0x7ffff7dd0760 <_IO_2_1_stdout_>) at filedoalloc.c:101
#3 0x00007ffff7a72379 in __GI__IO_doallocbuf (fp=fp@entry=0x7ffff7dd0760 <_IO_2_1_stdout_>) at genops.c:365
#4 0x00007ffff7a71498 in _IO_new_file_overflow (f=0x7ffff7dd0760 <_IO_2_1_stdout_>, ch=-1) at fileops.c:759
#5 0x00007ffff7a6f9ed in _IO_new_file_xsputn (f=0x7ffff7dd0760 <_IO_2_1_stdout_>, data=<optimized out>, n=23)
at fileops.c:1266
#6 0x00007ffff7a3f534 in _IO_vfprintf_internal (s=0x7ffff7dd0760 <_IO_2_1_stdout_>,
format=0x5555555549c8 "sizeof(char) ------ %ld\n", ap=ap@entry=0x7fffffffe330) at vfprintf.c:1328
#7 0x00007ffff7a48f26 in __printf (format=<optimized out>) at printf.c:33
#8 0x0000555555554894 in main () at memset_test.c:20
(gdb)
Итак, это простоmalloc
код, вызываемый (более или менее косвенно) с помощью printf
, выполняющего свою работу в блоке памяти, непосредственно смежном с тем, который он вам дал (возможно, пометив его как использованный).
Короче говоря: вы взялипамять, которая была не вашей, и теперь она в первый раз модифицируется ее законным владельцем, когда ему это нужно;ничего особенно странного или интересного.