Tag Archives: Pointer

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);

Remember the error of using unaddressable value of a novice goer

Go test, report an error;

Error in go test panic: reflect: reflect. Value. Set using addressable value [recovered].

Solution: generally, there is an error of using unaddressable value, which indicates that the pointer value passed is incorrect. For example, if the pointer address needs to be passed, but the value is passed. At that time, I had a hunch that DB should have passed a non pointer when finding. After verification, it was.

So, the summary is: when updating in Gorm, you can not pass the pointer (if you want to use the returned primary key, you still need to pass the pointer), but when querying, you must pass it, even if it is slice or map type.

Two dimensional array and pointer to one dimensional array

First, the previous two-dimensional array:

int a[3][4]={1,2,3,4,5,6,7,8,9,1,2,3};

How to operate a pointer for a two-dimensional array like this:
the first concept is that a two-dimensional array has rows and columns.

    the first point is that the * operator accesses the column, and the second point is that the [] subscript operator also accesses the column.

For example, a, * a, a [2], * (a + 2)
A: A is the address of the first row, while * a is the address of the first row and zero column, which is the address of the first row and zero column.
A [2]: the subscript accesses the column of the row, that is, the address of two rows and 0 column.
* (a + 2): a + 2 accesses the address at the beginning of the second line, and a * sign accesses the address at column 0 of the second line.

Pointer to one-dimensional array: int (* P) [4];
when this pointer P points to a two-dimensional array, every P + 1 skips four elements and points directly to the next line.