C, первый член структуры - PullRequest
       1

C, первый член структуры

1 голос
/ 05 октября 2010

У меня есть еще один вопрос новичка С: Почему первый член структуры возвращает адрес, не похожий на собственный указатель-адрес структуры, если не инициализирован?

Пример:

struct Metadata {
    int message_ID;
    //other members...
    //...
};

struct Metadata* baseMetadataPtr = (struct Metadata*) malloc(sizeof(struct Metadata)*100);

printf("baseMetadataPtr: %d\n", baseMetadataPtr);
//consoll says "baseMetadataPtr: 2636496"

printf("baseMetadataPtr->message_ID: %d\n", baseMetadataPtr->message_ID);
//consoll says "baseMetadataPtr->message_ID: 2621636"

Ответы [ 5 ]

8 голосов
/ 05 октября 2010

Ваш второй printf звонок неправильный.Это должно быть:

printf("baseMetadataPtr->message_ID: %p\n", &baseMetadataPtr->message_ID);
//         need to use %p for pointer ^     ^ need unary-& operator

Как написано прямо сейчас, печатается целое значение message_ID.Вам нужно взять адрес baseMetadataPtr->message_ID.Также обратите внимание, что если вы хотите напечатать указатель, вы должны использовать спецификатор формата %p, а не %d (который печатает целое число).

Адрес первого члена данных типа структурыОбъект всегда будет таким же, как адрес самого объекта типа структуры.Это гарантировано, потому что в начале структуры заполнение не допускается (однако заполнение допускается между элементами данных или в конце структуры).

1 голос
/ 05 октября 2010

Мне нравятся рисунки.Они помогают мне «видеть» вещи

struct Metadata *baseMetadataPtr;
baseMetadataPtr = malloc(100 * sizeof *baseMetadataPtr);

С этим, и, предполагая линейную память (прямоугольники ниже) и игнорируя требования к пространству для различных объектов, мы имеем

|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|...|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|...
   ^^^^^^^ baseMetadataPtr
  (of type (struct Metadata *))

   ******* ===========================>
|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|...|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|...
   ^^^^^^^ baseMetadataPtr             ^^^^^^ ^^^^^^^ ^^^^^^^ ^^^^^ ^^ ...
  (of type (struct Metadata *))        *baseMetadataPtr (struct Metadata)
                                               *(baseMetadataPtr+1)
                                                      baseMetadataPtr[2]

И, увеличение на левой части

   *baseMetadataPtr
|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|...
   ^^^ Message_ID (type (int))
       ^^^^^^^ Message_Len (type (size_t))
               ^^^^ ... other members, followed by another object of type (struct Metadata)
0 голосов
/ 05 октября 2010

Первый printf () печатает текущее значение указателя, IE, на какой адрес он указывает.

Второй printf печатает значение элемента сообщения Metadata message_ID.

Чтобы получить то, что вы хотите, попробуйте: printf ("baseMetadataPtr-> message_ID:% d \ n", & baseMetadataPtr-> message_ID);

0 голосов
/ 05 октября 2010

baseMetadataPtr->message_ID печатает значение переменной message_ID. Так как вы не инициализировали его, он содержит мусор. Чтобы распечатать его адрес, нужно сделать &baseMetadataPtr->message_ID. Также вам необходимо использовать спецификатор формата %p для печати значений указателя.

0 голосов
/ 05 октября 2010

Печатает адрес памяти указателя:

printf("baseMetadataPtr: %d\n", baseMetadataPtr); 

и это печатает адрес памяти переменной внутри структуры:

printf("baseMetadataPtr->message_ID: %d\n", &baseMetadataPtr->message_ID); 

И вот почему они не соседи.

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