Чем определяется размер указателя в C++?

Ответ

Размер указателя в C++ определяется разрядностью целевой платформы (архитектуры), так как указатель должен быть способен адресовать всё виртуальное адресное пространство процесса.

  • На 32-битных (x86) системах размер указателя обычно составляет 4 байта (32 бита), что позволяет адресовать до 4 ГБ памяти.
  • На 64-битных (x86-64, ARM64) системах размер указателя обычно составляет 8 байт (64 бита).

Ключевые моменты:

  • Размер указателя не зависит от типа данных, на который он указывает (int*, char*, MyClass*).
  • Размер указателя на функцию или указателя на член класса может отличаться от размера указателя на данные, но это зависит от ABI (Application Binary Interface) компилятора и платформы.

Пример:

#include <iostream>

int main() {
    std::cout << "Platform pointer sizes:n";
    std::cout << "sizeof(int*):      " << sizeof(int*)      << " bytesn";
    std::cout << "sizeof(double*):   " << sizeof(double*)   << " bytesn";
    std::cout << "sizeof(void*):     " << sizeof(void*)     << " bytesn";
    // Указатели на функции могут быть другого размера
    std::cout << "sizeof(void(*)()): " << sizeof(void(*)()) << " bytesn";
    return 0;
}

Типичный вывод на 64-битной Linux/macOS:

sizeof(int*):      8 bytes
sizeof(double*):   8 bytes
sizeof(void*):     8 bytes
sizeof(void(*)()): 8 bytes

Ответ 18+ 🔞

Бля, ну вот смотри, тут про указатели в C++ объясняют, аж ебать мои старые костыли. Всё просто, как палка о двух концах, но если не врубиться, потом такие грабли по лбу получаешь, что удивление пиздец.

Короче, размер этой штуки — указателя — зависит целиком и полностью от того, на какой платформе твоя программа будет бегать. Это как обувь: на 32-битную ногу — один размер, на 64-битную — совсем другой.

  • Если ты на старой, 32-битной системе (x86), то указатель у тебя будет ровно 4 байта. Это как раз 32 бита, и адресовать он может до 4 гигов памяти. Больше — ни-ни, упрётся в потолок.
  • А вот если ты на современной 64-битной (x86-64, ARM64), то тут уже раздолье — целых 8 байт (64 бита). Места дохуища, адресуй не хочу.

А теперь самое важное, чтобы ты не облажался:

  • Размер указателя вообще похуй, на какой тип он указывает. int*, char*, MyClass* — все они будут одного размера для данных. Это просто адрес в памяти, ему всё равно, что там лежит.
  • Но вот с указателями на функции или на члены класса может быть засада. Их размер иногда может отличаться! Это уже от компилятора и платформы зависит, так что тут доверия ебать ноль — всегда проверяй.

Вот, смотри пример, чтобы не быть голословным:

#include <iostream>

int main() {
    std::cout << "Platform pointer sizes:n";
    std::cout << "sizeof(int*):      " << sizeof(int*)      << " bytesn";
    std::cout << "sizeof(double*):   " << sizeof(double*)   << " bytesn";
    std::cout << "sizeof(void*):     " << sizeof(void*)     << " bytesn";
    // Указатели на функции могут быть другого размера
    std::cout << "sizeof(void(*)()): " << sizeof(void(*)()) << " bytesn";
    return 0;
}

Если скомпилишь и запустишь на нормальном 64-битном железе, скорее всего, увидишь:

sizeof(int*):      8 bytes
sizeof(double*):   8 bytes
sizeof(void*):     8 bytes
sizeof(void(*)()): 8 bytes

Вот и вся магия. Главное — запомни эту простую связку: архитектура -> размер указателя. А то будешь потом гадать, почему на одном компе работает, а на другом — нихуя.