Какой размер указателя в 64-битном режиме?

Ответ

В 64-битном режиме (архитектура x86-64, также известная как AMD64) размер любого указателя — 8 байт (64 бита). Это фундаментальное отличие от 32-битного режима, где указатель занимает 4 байта.

Проверка и последствия:

#include <iostream>
#include <cstdint>

int main() {
    std::cout << "sizeof(int*): " << sizeof(int*) << " bytesn";
    std::cout << "sizeof(void*): " << sizeof(void*) << " bytesn";
    std::cout << "sizeof(std::string*): " << sizeof(std::string*) << " bytesn";
    // Все выводы будут равны 8 на 64-битной системе.

    // Практическое следствие: структуры с множеством указателей становятся "тяжелее".
    struct Node32 { Node32* next; int data; }; // Размер ~8 байт в 32-битном
    struct Node64 { Node64* next; int data; }; // Размер ~16 байт в 64-битном (из-за выравнивания)
    std::cout << "Size of Node64: " << sizeof(Node64) << " bytesn";
    return 0;
}

Ключевые технические детали:

  1. Адресное пространство: 64-битный указатель теоретически может адресовать 16 эксабайт (2^64). Однако, современные процессоры x86-64 используют только 48 бит (256 ТБ) для виртуальных адресов, что более чем достаточно для любых практических задач.
  2. Влияние на производительность: Увеличение размера указателей может привести к большему потреблению памяти (особенно в структурах данных вроде связных списков или графов) и более частым промахам кэша. В высокопроизводительном коде иногда используют 32-битные индексы или относительные указатели внутри ограниченных пулов памяти, чтобы смягчить этот эффект.

Ответ 18+ 🔞

А, ну вот, классика! Сидишь ты такой, пишешь код, и тут бац — переход на 64-бита. И первое, что тебя накрывает, как медным тазом — это размер указателей. Запомни раз и навсегда, ёпта: в этом новом мире любой указатель — это ровно 8 байт, 64 бита. Не 4, как в старые добрые времена, а именно 8. Это, блядь, фундаментально, как закон тяготения.

Вот смотри, проверка-то какая простая, хоть сейчас в компилятор суй:

#include <iostream>
#include <cstdint>

int main() {
    std::cout << "sizeof(int*): " << sizeof(int*) << " bytesn";
    std::cout << "sizeof(void*): " << sizeof(void*) << " bytesn";
    std::cout << "sizeof(std::string*): " << sizeof(std::string*) << " bytesn";
    // Все выводы будут равны 8 на 64-битной системе.

    // Практическое следствие: структуры с множеством указателей становятся "тяжелее".
    struct Node32 { Node32* next; int data; }; // Размер ~8 байт в 32-битном
    struct Node64 { Node64* next; int data; }; // Размер ~16 байт в 64-битном (из-за выравнивания)
    std::cout << "Size of Node64: " << sizeof(Node64) << " bytesn";
    return 0;
}

Видишь? Всё едино — на int, на void или на какую-нибудь хитрожопую std::string — указатель будет восьмибайтовым монстром. И вот тут начинается самое интересное.

А теперь детали, от которых волосы дыбом:

  1. Адресное пространство. Теоретически этот 64-битный монстр может тыкать в 16 эксабайт памяти — это, блядь, овердохуища, цифры с которыми мозг просто отключается. На практике же современные процессоры используют только 48 бит, но и это — 256 терабайт. Представляешь? Доверия к таким масштабам — ноль ебать, но жить с этим можно.
  2. Влияние на производительность — вот где собака зарыта. Память-то твои структуры начинают жрать как не в себя. Раньше связный список Node весил условно 8 байт, а теперь — 16, из-за выравнивания. И всё, приехали: кэш-промахи учащаются, производительность проседает. Поэтому в хайперформанс коде умные дядьки начинают выкручиваться: используют 32-битные индексы вместо указателей или какие-нибудь относительные смещения внутри своего пула памяти. В общем, мозгой надо шевелить, э бошка думай!

Короче, суть в чём: 64 бита — это не просто «ой, цифра больше». Это другая вселенная, где твои старые структуры данных внезапно становятся пухлыми и неповоротливыми. Сам от этого факта первый раз охуел, но что поделать — прогресс, ёперный театр.