Хорошая идея, если вы хотите знать, как все это работает, - запускать ваше приложение в отладчике. Это действительно дерьмо, чтобы понять, что происходит.
С любым отладчиком все в порядке, но я лучше знаю windbg, так что вот несколько советов о том, с чего начать, когда немного измененная версия вашего кода, как предложил Грег, вам нужна int *.
CHANGE:
char *x = &x4;
TO:
int *x = &i;
DELETE:
x = &x4;
MOVE (первая переменная, перед x1):
int i;
НОВОЕ ИЗМЕНЕНИЕ (намного проще читать и делать как раньше (x-i) - это случайные / не входящие в объем значения):
printf("%02d: %08x : %08x\n", i, x + i, *(x + i));
Это изменение будет эффективно отображать адрес кадра стека и значение.
В windbg откройте окна вызовов, памяти, потоков и команд, чтобы вы могли видеть их все.
Скомпилируйте ваш код C с помощью компилятора, я использовал MSVC (вы можете получить его для ознакомления бесплатно), скомпилируйте с помощью «Visual Studio 20 ## Command Prompt» с помощью «cl / Zi your.c». Загрузите Windbg (средства отладки для Windows), нажмите Ctrl + E или используйте «открыть исполняемый файл».
Загрузите следующие окна, чтобы вы могли видеть их все одновременно, Звонки, Местные жители, Память, Потоки и Команды.
В командном окне установите точку останова на DoTestStack с помощью «bu DoTestStack».
начать отладку командой "g".
После того, как вы дойдете до точки останова, используйте «p» для одного шага, вы также должны получить всплывающее окно с исходным кодом, или вы можете наблюдать за выводом вашего приложения, после того, как оно запустится в цикле for, вернитесь к Windbg. Откройте окно памяти и установите для него «Указатели и символы» для типа адреса в «i», оно должно иметь отладочную информацию из компиляции (/ Zi) и выдаст вам список «Указателей и символов», начиная с указатель на адрес я.
Выходные данные должны быть идентичны тестовому коду (после внесения предложенных мной изменений), если вы продолжите нажимать p, вы также увидите, что в окне памяти вы можете наблюдать значение i, изменяющееся при выполнении, однако поскольку printf теперь печатает другие значения, вы просто увидите его в исходном «0» на выходе;).
Вы можете альтернативно использовать команду windbg dds (обратите внимание, что значение i равно 0xb, так как оно находится в середине цикла for)
0:000> dds i
0018ff24 0000000b
0018ff28 02586bf9
0018ff2c 0018ff24
0018ff30 0018ff38
0018ff34 00401118 a!TestStack+0x8 [c:\temp\a.c @ 33]
0018ff38 0018ff40
0018ff3c 00401128 a!main+0x8 [c:\temp\a.c @ 35]
0018ff40 0018ff88
0018ff44 00401435 a!__tmainCRTStartup+0xf8 [f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c @ 257]
0018ff48 00000001
0018ff4c 003c1e48
Это идентично (кроме поддержки символов) измененному тестовому коду;
00: 0018ff24 : 00000000
01: 0018ff28 : 02586bf9
02: 0018ff2c : 0018ff24
03: 0018ff30 : 0018ff38
04: 0018ff34 : 00401118
05: 0018ff38 : 0018ff40
06: 0018ff3c : 00401128
07: 0018ff40 : 0018ff88
08: 0018ff44 : 00401435
09: 0018ff48 : 00000001
10: 0018ff4c : 003c1e48