LINUX.ORG.RU

История изменений

Исправление Vic, (текущая версия) :

Компилятор gcc на моей машине тебя перехитрил и не стал переменную idx помещать следом за s.

    ...
    printf("%lx (%p+%lx != %p)\n", ccc, &s, idx, &idx);
    ...

    gcc version 8.1.0 (i686-posix-dwarf-rev0, Built by MinGW-W64 project)

    4c (0028FED0+10 != 0028FECC)

Судя по ассемблерному листингу, он поместил idx перед s (имеет полное право так делать).

	...
	# struct SomeStruct s = {};
	mov	DWORD PTR [esp+48], 0	 # s
	mov	DWORD PTR [esp+52], 0	 # s
	mov	DWORD PTR [esp+56], 0	 # s
	mov	DWORD PTR [esp+60], 0	 # s
	# unsigned long idx = sizeof(s);
	mov	DWORD PTR [esp+44], 16	 # idx
	...
Классический пример, когда вышли за логичные пределы памяти внутри своей программы. В данном случае, прочитали память из свободных ячеек памяти стека, что с точки зрения логики программы имеет смысл «прочитали какой-то мусор».

Исправление Vic, :

Компилятор gcc на моей машине тебя перехитрил и не стал переменную idx помещать следом за s.

    ...
    printf("%lx (%p+%lx != %p)\n", ccc, &s, idx, &idx);
    ...

    gcc version 8.1.0 (i686-posix-dwarf-rev0, Built by MinGW-W64 project)

    4c (0028FED0+10 != 0028FECC)

Судя по ассемблерному листингу, он поместил idx перед s (имеет полное право так делать).

	...
	# struct SomeStruct s = {};
	mov	DWORD PTR [esp+48], 0	 # s
	mov	DWORD PTR [esp+52], 0	 # s
	mov	DWORD PTR [esp+56], 0	 # s
	mov	DWORD PTR [esp+60], 0	 # s
	# unsigned long idx = sizeof(s);
	mov	DWORD PTR [esp+44], 16	 # idx
	...
Классический пример, когда вышли за логичные пределы памяти внутри своей программы. В данном случае, прочитали память из свободной ячейки стека, в которой потом расположится адрес возврата из printf().

Исправление Vic, :

Компилятор gcc на моей машине тебя перехитрил и не стал переменную idx помещать следом за s.

    ...
    printf("%lx (%p+%lx != %p)\n", ccc, &s, idx, &idx);
    ...

    gcc version 8.1.0 (i686-posix-dwarf-rev0, Built by MinGW-W64 project)

    4c (0028FED0+10 != 0028FECC)

Судя по ассемблерному листингу, он поместил idx перед s (имеет полное право так делать).

	...
	# struct SomeStruct s = {};
	mov	DWORD PTR [esp+48], 0	 # s
	mov	DWORD PTR [esp+52], 0	 # s
	mov	DWORD PTR [esp+56], 0	 # s
	mov	DWORD PTR [esp+60], 0	 # s
	# unsigned long idx = sizeof(s);
	mov	DWORD PTR [esp+44], 16	 # idx
	...

Исходная версия Vic, :

Компилятор gcc на моей машине тебя перехитрил и не стал переменную idx помещать следом за s.

    ...
    printf("%lx (%p+%lx != %p)\n", ccc, &s, idx, &idx);
    ...

    gcc version 8.1.0 (i686-posix-dwarf-rev0, Built by MinGW-W64 project)

    4c (0028FED0+10 != 0028FECC)

Судя по ассемблерному листингу, поместил idx перед s.

	...
	# struct SomeStruct s = {};
	mov	DWORD PTR [esp+48], 0	 # s
	mov	DWORD PTR [esp+52], 0	 # s
	mov	DWORD PTR [esp+56], 0	 # s
	mov	DWORD PTR [esp+60], 0	 # s
	# unsigned long idx = sizeof(s);
	mov	DWORD PTR [esp+44], 16	 # idx
	...