An in depth look at the C language structure

  • 2020-06-12 10:08:16
  • OfStack

After a long time of development, I dare not say That I have mastered C. After all, many details will be forgotten in the process of learning, and then I will slowly pick them up through practice. So it's only a proficiency level.

The implementation of Linux kernel is extensive and profound. From the implementation of offsetof to the later container_of, why can the pointer of the whole structure be obtained through the members of the structure? This is thanks to the implementation of the offsetof macro. This macro has been covered in previous posts, but not in enough depth. Today's example is enough to fully understand how the structure itself works. Let's take a look at this example:


#include <stdio.h>
//32 On a bit system, the structure defaults to when alignment is not specified 4 Byte alignment  
typedef struct __ST
{
 int id ;  //4
 char *name ; //4
 float math ; //4
}ST;
int main()
{
 ST st ;
 // Gets the control of the structure 1 The first address of an element  
 int *ptr_0 = (int *)(&st);
 printf("st:  %p  ptr:  %p \n",&st,ptr_0);
 // To the structure 1 An element assignment  
 *ptr_0 = 100 ;
 printf("*ptr_0 = %d\n",*ptr_0);
 // Gets the control of the structure 2 The first address of an element , Because the first 2 An element is 1 Level pointer, so you need to use 1 a 2 Level pointer to connect  
 char **ptr_1 = (char **)((int)&st+4) ;
 printf("ptr_1:%p\n",ptr_1);
 // The regulation of a structure 2 An element assignment  
 *ptr_1 = "hello world";
 printf("ptr_1:%s\n",*ptr_1);
 // Gets the control of the structure 3 The first address of the element. The first address is calculated according to the alignment principle 3 The address of the element  
 float *ptr_2 = (float *)((int)&st+8) ;
 printf("ptr_2:%p \n",ptr_2);
 // The regulation of a structure 3 Assign values to the elements  
 *ptr_2 = 96.78 ;
 printf("ptr_2:%.2f \n",*ptr_2);
 // Outputs the values of all the members of the structure  
 printf("st.id = %d  st.name = %s  st.math = %.2f\n",st.id,st.name,st.math);
  return 0;
}

Isn't the offset calculated by the alignment principle actually the principle of the offsetof macro?


#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

Going on to look at linked lists, function Pointers, and other structures-related concepts, it suddenly feels like an act that clears the way for learning.

conclusion


Related articles: