2017-02-15 2 views
0

Может кто-нибудь объяснить, почему следующий код дает разные результаты во втором printf, если я прокомментирую первую строку printf или нет, в 64 бит?64-битный ELF дает необъяснимые результаты

/* gcc -O0 -o test test.c */ 
#include <stdio.h> 
#include <stdlib.h> 

int main() { 

    char a[20] = {0}; 
    char b = 'a'; 
    int count=-1; 


    // printf("%.16llx %.16llx\n", a, &b); 
    printf("%x\n", *(a+count)); 

return 0; 
} 

Я получаю следующие результаты второго Printf:

  • прокомментировал: 0
  • раскомментирована: 61

Спасибо заранее!

iansus

ответ

0

Может кто-то объяснить, почему следующий код дает разные результаты на второй Printf, если я комментирую первую PRINTF линию или не

Ваша программа использует a[-1], и, таким образом обнаруживает неопределенное поведение. Все, что угодно может случиться, и выяснить, почему именно одна или другая вещь происходит бессмысленно.

Точная причина в том, что вы читаете память, которая записывается первым printf (при комментировании).

я получить другой результат (который, как ожидается, с неопределенным поведением):

// with first `printf` commented out: 
ffffffff 

// with it commented in: 
00007fffffffdd20 00007fffffffdd1b 
ffffffff 

Вы могли видеть, где эта память записывается, установив точку наблюдения GDB на нем:

(gdb) p a[-1] 
$1 = 0 '\000' 
(gdb) p &a[-1] 
$2 = 0x7fffffffdd1f "" 
(gdb) watch *(int*)0x7fffffffdd1f 
Hardware watchpoint 4: *(int*)0x7fffffffdd1f 
(gdb) c 
Continuing. 
Hardware watchpoint 4: *(int*)0x7fffffffdd1f 

Old value = 0 
New value = 255 
main() at t.c:12 
12  printf("%.16llx %.16llx\n", a, &b); 

It мой пример выше, значение записывается как часть инициализации count=-1. То есть, с моей версией gcc, count находится непосредственно перед a[0]. Но это может зависеть от версии компилятора, как именно был создан этот компилятор и т. Д. И т. Д.

Смежные вопросы