当前位置:网站首页>Hello C (VII) - structure

Hello C (VII) - structure

2022-06-24 23:42:00 Tianshan old demon

One 、 Introduction to structure

1、 Structure definition

There are two common methods for defining a structure :

The first method :

struct person{
    char *name;
    unisgned int age;
};

The second method :

typedef struct person{
    char *name;
    unsigned int age;
}Person;

person The instance declaration is as follows :

Person person;// Make a statement person object 
Person *ptrPerson = (Person*)malloc(sizeof(Person));// Make a statement person object , And allocate memory 

2、 Initialization of structure

Initializing a structure object using a structure declaration :

Person person;
person.name = (char *)malloc(strlen(“socprio”) + 1);
strcpy(person.name, “scorpio”);
person.age = 30;

Initialization of a structure declared using a structure pointer :

Person *ptrPerson;
prtPerson = (Person *)malloc(sizeof(Person));
ptrPerson->name = (char *)malloc(strlen(“scorpio”) + 1);
strcpy(ptrPerson->name, “scorpio”);
prtPerson->age = 30;

3、 The problem of structure release

When a structure is defined, memory is allocated for the structure , However, the runtime system will not automatically allocate memory for pointers inside the structure , When the structure is destroyed , The runtime system will not automatically release the memory pointed to by the pointer inside the structure . The pointer inside the structure points to the memory, which is generally dynamically allocated , Release after use , Otherwise, it will cause memory leakage .

4、 Dynamic allocation of memory overhead avoidance

Repeatedly allocating and then releasing structures incurs overhead , This can lead to huge performance bottlenecks . The migration method to solve this problem is to maintain a separate table for the allocated structure . When the user does not need a structure instance , Return it to the structure pool . When a structure instance is required , Get an object from the structure pool . If there are no available structures in the structure pool , A structure instance will be automatically and dynamically allocated .

Two 、 Structure macro

1、offsetof macro

offsetof Calculate the offset of the structure member from its first address according to its type and name . The macro is defined as follows :

#define offsetof(type, member) ((size_t)(&((type *)0)->member))

( (TYPE *)0 ): 0 Address enforcement  " transformation "  by  TYPE Pointer to structure type

((TYPE *)0)->MEMBER : visit TYPE The structure of the MEMBER Data member

&( ( (TYPE *)0 )->MEMBER): Take out TYPE Data members in the structure MEMBER The address of

(size_t)(&(((TYPE*)0)->MEMBER)): The result is converted to size_t type

offsetof The macro will first 0 Convert to structure pointer type , Then reference the member variable and take its address . Because the first address of the structure is 0, So the address of the member variable is the offset of the member from the first address of the structure .

Commonly used in modern compilers

#define offsetof(type, member) __builtin_offsetof(type, member)

2、container_of macro

container_of According to the Member Address 、 Structure type and member name to calculate the first address of the structure , Its definition is as follows :

#define container_of(ptr, type, member) ({ \
    const typeof( ((type *)0)->member ) *__mptr = (ptr); \
    (type *)( (char *)__mptr - offsetof(type,member) );})


#include <stdio.h>

#define offsetof(type, member) ((size_t)&((type *)0)->member)

#define container_of(ptr, type, member) ({ \
    const typeof( ((type *)0)->member ) *__mptr = (ptr); \
    (type *)( (char *)__mptr - offsetof(type,member) );})

struct test{
    char a;
    int b;
    short c;
    char *p;
    double d;
}__attribute__((aligned(4)));

int main(int argc, char **argv)
{
    struct test s;
    printf("offset a=%lu\n",offsetof(struct test,a));
    printf("offset b=%lu\n",offsetof(struct test,b));
    printf("offset c=%lu\n",offsetof(struct test,c));
    printf("offset p=%lu\n",offsetof(struct test,p));
    printf("offset d=%lu\n",offsetof(struct test,d));

    printf("s=%p\n",container_of(&s.a,struct test,a));
    printf("s=%p\n",container_of(&s.p,struct test,p));

    return 0;
}

Running results :

offset a=0
offset b=4
offset c=8
offset p=16
offset d=24
s=0x7fffc8590cf0
s=0x7fffc8590cf0

原网站

版权声明
本文为[Tianshan old demon]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202211118041245.html