When C language refers to a user-defined type as a parameter, an error segmentation fault is reported

Problem Description:

In the data structure operation, a function to initialize the table is written:


#define InitSize 100
#define ElemType int

typedef struct {
    ElemType* list;
    int len;
    int size;
} sql_;


int sql_init(sql_ *head) {
    (*head).list = (ElemType*)malloc(InitSize*sizeof(ElemType));
    (*head).len = 0;
    (*head).size = InitSize;

    return 1;
}

int main() {
    sql_ L1;
    sql_init(&L1);

    sql_*L2;
    sql_init(L2);

    system("pause");
}

However, an error is reported at runtime: segmentation fault

  After entering the debugging interface, it is found that L1 has been initialized successfully, but there is a problem when it comes to L2. What is the difference between L1 and L2 initialization codes?

Analyze the problem:

    sql_ L1;
    sql_init(&L1);

    sql_*L2;
    sql_init(L2);

It can be seen that L1 is declared as SQL_ Type; L2 is declared as SQL*_ Type.

There is no warning in vscode, but there is a warning and error in vs2019, and it can not even be compiled. So what’s the reason?

Through network retrieval, we get such an article: int * a in C + +; int & a; int & * a; int * & a_ Tianya Mingyue Dao blog – CSDN blog

Inspired by the quoted concepts mentioned in the article, we made the following attempts:

sql_ L;
    sql_*L2 = &L;
    sql_init(L2);

  After such processing, the initialization can be completed successfully. Therefore, the following guess is made:

When defining a macro type, only SQL is declared_ Type, but for SQL_* The type is not declared, so it is declared in main   sql_  *  L1; The compiler can’t find the prototype, so it can’t reference SQL when declaring parameters_* Type, so vs the more stringent compiler found this problem and told L2 that memory could not be allocated.

resolvent:

Using predefined SQL_ Type declaration, use its reference when parameters need to be passed & amp; L as SQL_* Arguments of type, that is, the method of initializing L1 mentioned earlier:

    sql_ L1;
    sql_init(&L1);

Read More: