Welcome to “Algorithms and the Beauty of Programming” ↑ pay attention to us! \

This article was first published on the wechat official account “Beauty of Algorithms and Programming”. Welcome to follow and learn more about this series of blogs in time.

1 problem Definition

I believe we must have used the structure in the process of C language program development, I do not know whether you have studied the structure of the member variable offset related knowledge, this article will share with you about the C language structure offset some thinking.

Let’s start with a simple case in which the structure type is defined as follows:

struct node_t{
    char a;
    int b;
    int c;
};
Copy the code

And the structure is 1Byte aligned \

#pragma pack(1)
Copy the code

Struct node_t = c; (Note: The offset here refers to the offset relative to the starting position of the structure.)

2 Solution

Different people may come up with different solutions to this problem. Here are a few possible solutions:

Method a

If you are familiar with c library functions, the first thing that comes to mind is the offsetof function (which is actually just a macro, let’s call it that). In Linux class operating systems, you can directly view the prototype of the man 3 offsetof function as follows: \

 #include <stddef.h>       
 size_t offsetof(type, member);
Copy the code

With the above library functions, we can do it in one line of code:

offsetof(struct node_t, c);
Copy the code

Of course, that’s not the focus of this article, so read on.

Method 2

When we are not familiar with c language library functions, don’t worry at this time, we can still use our own methods to solve the problem.

The most direct way to think about it is:

Struct member c address minus struct start address

Let’s start by defining a node structure variable:

struct node_t node;
Copy the code

Next, calculate the offset of the member variable c:

(unsigned long)(&(node.c)) - (unsigned long)(&node)
Copy the code

Where &(node.c) is the address of the struct member variable c and is forcibly converted to an unsigned long.

The &node is the starting address of the structure, which is also forcibly converted to an unsigned long.

Finally, we subtract the above two values to get the offset of member variable C.

Method three

Without the help of library functions, the offset of member variable C can be obtained by calculation. But as programmers, we should be thinking, can we make some improvements to the above code to make our code more concise? Before making specific improvements, we should analyze the existing problems.

The most important problem is that we define a structure variable node in order to calculate the offset of the structure member variables. Although there is no restriction in the problem that we can customize variables, when we encounter a strict problem that does not allow custom variables, it is time to think of a new solution.

Before we discuss the new solution, let’s first discuss a knowledge point about offset:

This is A simple geometric problem, suppose we move from point A to point B on the coordinate axis, how do we calculate the offset of B with respect to A? This is A very simple question for us, and most of us will probably blurt out the answer as B-A.

So is this answer entirely correct? The answer is clearly not, and the reason is that when A is the origin of the coordinates A equals 0, the answer B minus A simplifies to B.

What does this simple little question tell us?

We combine the idea of solution 2 and the above knowledge points, is not soon get the following correlation:

(unsigned long)(&(node.c)) - (unsigned long)(&node)
Copy the code

And \

B - A
Copy the code

We know from the above that when A is the origin, B minus A simplifies to B. Similarly, when node’s memory address is 0 (&node==0), the code above can be simplified to: \

(unsigned long)(&(node.c))
Copy the code

Node memory address ==0, so

Node. c // Member variable c in structure nodeCopy the code

We can write it another way:

((struct node_t *)0)->c
Copy the code

(struct node_t = 0) (struct node_t = 0) (struct node_t = 0) (struct node_t = 0)

Note: this is only the use of the compiler’s characteristics to calculate the structure offset, does not have any operation on the memory address 0, some students may have some questions about this problem, can refer to the C language structure member variable access mode of a point of thought.

Struct node_t node (struct node_t node)

(unsigned long)(&(((struct node_t *)0)->c))
Copy the code

Conclusion \ 3

In this paper, the offset of the structure variable of C language leads to the problem. From the initial call library function to manual calculation, the solution idea of the problem is put forward step by step. Finally, the compiler calculates the memory address 0 to solve the problem directly with one line of code, which is very skillful.

\

More interesting articles:

\

\

Sichuan Tourism Institute Where2Go team


* * * * * * * * \

Wechat: The beauty of algorithms and programming

Long press to identify the QR code to follow us!

Tips: Click on the lower right corner of the page “Write a message” to comment, looking forward to your participation! Welcome to forward!

\