开发者

C, first member of struct

I have yet another newbie C question: Why does the first member of a struct return an adress not similar to the structs own pointer-adress when not initialized?

Example:

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"


Your second printf call is wrong. It should be:

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

As written right now, the integer value of message_ID is being printed. You need to take the address of baseMetadataPtr->message_ID. Also note that if you want to print a pointer, you should use the %p format specifier, not %d (which prints an integer).

The address of the first data member of a struct-type object will always be the same as the address of the struct-type object itself. This is guaranteed because no padding is permitted at the beginning of a struct (padding is permitted between data elements or at the end of the struct, though).


I like drawings. They help me "see" stuff

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

With that, and assuming a linear memory (the boxes below), and ignoring the space requirements for the different objects, we have

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

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

And, zooming in on the part on the left

   *baseMetadataPtr
|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|...
   ^^^ Message_ID (type (int))
       ^^^^^^^ Message_Len (type (size_t))
               ^^^^ ... other members, followed by another object of type (struct Metadata)


This prints the memory address of the pointer:

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

and this prints the memory address of the variable inside the struct:

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

And that's why they are not neighbors.


baseMetadataPtr->message_ID prints the value of the variable message_ID. Since you have not initialized it, it is containing garbage. To print its address you need to do &baseMetadataPtr->message_ID. Also, you need to use the format specifier %p to print pointer values.


The first printf() prints the current value of the pointer, IE, what address it is pointing.

The second printf prints the value of the Metadata member message_ID.

To get what you want, try: printf("baseMetadataPtr->message_ID: %d\n", &baseMetadataPtr->message_ID);

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜