Имейте в виду разницу между структурой и указателем на структуру.
Предположим, что 32-битный компилятор.
Давайте создадим-структуру:
struct point_i {
int x;
int y;
};
Эта структура имеет два элемента Int. Каждое целое число имеет размер 4 байта, поэтому размер структуры составляет восемь байтов.
Затем используйте:-структуру
strut point_i my_point; // 8 bytes allocated, lets assume that they
// are located at address 0x10000000.
my_point.y = 10;
Когда вы сделаете это, то компилятор знает, где находится my_point и его размер, и он также знает, где член y
является относительно структуры. Так он компилирует (очень грубо) на что-то вроде:
MOV [0x10000004], 10 ;; Notice that its 0x10000000 + 4.
;; The first four bytes are X so we skip them
;; to get to Y and put 10 in that memory address.
С другой стороны, если у вас есть указатель:
strut point_i *another_point; // 4 bytes allocated, the pointer size.
// Let's assume in 0x20000000.
another_point = get_random_point(); // Get an address to some random point.
another_point->y = 10; // You have to use -> to reference the member
// because you are not dealing with an struct
// anymore but a *pointer* to said struct.
И поскольку компилятор не имеет ни малейшего представления, что решения вы собираетесь поставить в этом указателе он должен генерировать код, который немного отличается.
MOV EBX, [0x20000000] ;; 0x20000000 has your pointer. So we fetch it.
MOV [EBX+4], 10 ;; Dereference the pointer and put 10 in Y.
;; You can see that we now have two memory references,
;; one to get the pointer and another to get where it
;; points to. So it is a layer of indirection.
Обратите внимание, что это очень упрощенный вид на мир. Компилятор/компоновщик и операционная система разрешают адреса памяти в ваших программах. Но он должен прояснить, что происходит за кулисами. Разрушение указателя является основной частью C.
Мне бы очень хотелось сказать, что это одно и то же, но это похоже на то, что происходит * неявное * «разыменование», которое происходит. – user2864740