Неверный размер указателя - PullRequest
0 голосов
/ 02 марта 2020

Я изучаю указатели и обнаружил, что получаю неверный размер указателя.

Я узнал, что, поскольку p_num - это указатель на int, он должен показывать 4 байта, но показывает 8.

Что может быть причиной этого?

#include <stdio.h>

int main()
{
    int num = 0;
    int * p_num = NULL;

    num = 10;

    printf("num address: %p\n", &num);
    printf("num size: %zd\n", sizeof(num));
    printf("num value: %d\n\n", num);

    p_num = &num;

    printf("p_num address: %p\n", (void*)&p_num);
    printf("p_num size: %zd\n", sizeof(p_num));
    printf("p_num value: %p\n", p_num);
    printf("p_num value pointed: %d\n", *p_num);

    return 0;
}

Вывод:

num address: 0x7fffcb0e8ffc
num size: 4
num value: 10

p_num address: 0x7fffcb0e8ff0
p_num size: 8
p_num value: 0x7fffcb0e8ffc
p_num value pointed: 10

Ответы [ 5 ]

2 голосов
/ 02 марта 2020

Что может быть причиной этого?

Размер указателя зависит от архитектуры. В 32-разрядных архитектурах указатель обычно занимает 4 байта в памяти, в 64-разрядных архитектурах обычно 8 байт.

Таким образом, нет ничего плохого в программе или самой системе, если вы используете 64-разрядный архитектура, как вы сказали в комментариях . Вы только что ошибочно предположили:

Я узнал, что ... указатель на int ... должен показывать 4 байта.

Более того обычно это действует для всех типов указателей, а не только для указателей на int. Обычно они имеют одинаковый размер в памяти, но стандарт не требует, чтобы, как вы можете видеть в цитате из ISO / IEC 9899: 2011 (C11) в этом ответе относительно точный вопрос для этого.

Размер указателя также может отличаться от размера объекта, на который указывает указатель. Различия между размером объекта указателя и размером объекта, на который указывает указатель.

2 голосов
/ 02 марта 2020

Я узнал, что, поскольку p_num - это указатель на int, он должен показывать 4 байта, но показывает 8.

Ваше предположение неверно.

int - это одна переменная.

int pointer - это еще одна переменная.

Итак две разные переменные и эти две переменные делают не должен иметь одинаковый размер.

Другими словами:

printf("p_num size: %zu\n", sizeof(p_num));   // Gives you the size of the pointer

printf("p_num size: %zu\n", sizeof(*p_num));  // Gives you the size of the pointed to object
                                   ^
                                   notice the *

В вашем случае вы видите, что размер int равен 4, а размер int pointer это 8. Это совершенно законно.

Скорее всего, вы могли бы сделать разницу в размере еще больше, посмотрев на char и char pointer. Тогда вы, скорее всего, увидите 1 для char и еще 8 для char pointer.

1 голос
/ 02 марта 2020

sizeof(p_num) - это размер указателя, а не размер того, на что он указывает.

sizeof(*p_num) - это размер того, на что он указывает.

Также, скобки не нужны. sizeof p_num и sizeof *p_num работают нормально. Круглые скобки нужны только для определения размеров типов (а не выражений) или сложных выражений.

0 голосов
/ 02 марта 2020

На 64-битных машинах размер указателя составляет 8 байт, поскольку указатель является адресом памяти . Указатель p_num указывает на переменную num, которая является одним из нескольких целочисленных типов. В 64-битной системе sizeof (int) = 4.

0 голосов
/ 02 марта 2020

Для адресации более 4 ГБ в памяти указатели должны иметь размер 8 байт. Адреса памяти размером более 4 ГБ не могут быть представлены с использованием 32 битов, то есть 4 байтов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...