嵌套指向结构体的指针,指向包含结构体的指针?

时间:2018-07-23 08:23:01

标签: c pointers struct unions double-pointer

首先,我有一个结构:

typedef struct {
    int type;
    union expr value;
}lval;

并定义为节省空间的并集:

union expr{
    long num;
    char* err;
    char* sym;
    sexpr* sexpr1;
};

,在sexpr*中是

typedef struct {
    int count;
    struct lval** cell;
}sexpr;

我尝试如下使用它,

void lval_del(lval* v){
     lval_del(v->value.sexpr1->cell[i]); 
}

但是我的编译器给了我一个警告:

  

参数类型不匹配:不兼容    指针类型为'lval *'和'structonymous :: lval *'。

当我尝试如下代码

lval* lval_add(lval* v,lval* x) {
    v->value.sexpr1->cell = realloc(v->value.sexpr1->cell, sizeof(lval*)*v->value.sexpr1->count);
    v->value.sexpr1->cell[v->value.sexpr1->count-1]=x;
    return v;
}

我得到同样的警告。

我忽略了警告并成功编译了警告,但是当我运行警告时,它崩溃了。我认为这是引起警告的问题。我该怎么解决?

编辑:我编译的完整代码如下:

typedef struct {
   int count;
   struct lval** cell;
}sexpr;

union expr{
    long num;
    char* err;
    char* sym;
    sexpr* sexpr1;
};

typedef struct {
    int type;
    union expr value;
}lval;

void lval_del(lval* v){
    switch (v->type) {
        case LVAL_NUM:
            break;
        case LVAL_ERR:
            free(v->value.err);
            break;
        case LVAL_SYM:
            free(v->value.sym);
            break;
        case LVAL_SEXPR:
            for (int i=0;i<v->value.sexpr1->count;i++){
                lval_del(v->value.sexpr1->cell[i]);
            }
            free(v->value.sexpr1->cell);
        default:break;
    }
}

lval* lval_add(lval* v,lval* x) {
    v->value.sexpr1->count ++;
    v->value.sexpr1->cell = realloc(v->value.sexpr1->cell,sizeof(lval*)*v->value.sexpr1->count);
    v->value.sexpr1->cell[v->value.sexpr1->count-1]=x;
    return v;
}

编辑:7.24 我通过按此顺序定义警告来消除警告。复杂的结构对我来说是一场噩梦,我放弃了尝试解决指针问题的尝试。下面是我的新代码,但仍然带有错误的指针。

struct init_lval;
struct init_sexpr;
typedef struct init_sexpr sexpr;
union expr{
    long num;
    char* err;
    char* sym;
    sexpr* sexpr1;
};
typedef struct init_lval lval;

struct init_lval
{
    int type;
    union expr value;
};

struct init_sexpr{
   int count;
   lval** cell;
};
lval* lval_add(lval* v, lval* x) {
    v->value.sexpr1->count ++;
    v->value.sexpr1->cell = realloc(v->value.sexpr1->cell,sizeof(lval*)*v->value.sexpr1->count);
    v->value.sexpr1->cell[v->value.sexpr1->count-1]=x;
    return v;
}
void lval_del(lval* v){
    switch (v->type) {
        case LVAL_NUM:
            break;
        case LVAL_ERR:
            free(v->value.err);
            break;
        case LVAL_SYM:
            free(v->value.sym);
            break;
        case LVAL_SEXPR:
            for (int i=0;i<v->value.sexpr1->count;i++){
                lval_del(v->value.sexpr1->cell[i]);
            }
            free(v->value.sexpr1->cell);
            free(v->value.sexpr1);
        default:break;
    }
    free(v);
}

3 个答案:

答案 0 :(得分:1)

struct lval** cell;无效,您没有struct lval,您typedeflval使用了匿名结构。

将其更改为lval **cell;

您也不会在v->value.sexpr1->count函数中递增add,因此它将始终写入相同的位置。

答案 1 :(得分:1)

这里的问题在于重新分配。您正在尝试重新分配从未分配过的内存。另外,您需要先在sexpr1

之类的表达式中使用内存,然后再分配给v->value.sexpr1->cell

尝试一下:

lval* lval_add(lval* v,lval* x) {
    v->value.sexpr1->count ++;
    if(v->value.sexpr1->cell == NULL) {
        v->value.sexpr1->cell = malloc(sizeof(lval*)*v->value.sexpr1->count);
    } else {
        v->value.sexpr1->cell = realloc(v->value.sexpr1->cell,sizeof(lval*)*v->value.sexpr1->count);
    }
    v->value.sexpr1->cell[v->value.sexpr1->count-1]= (struct lval*)x;
    return v;
}

并初始化要传递给lval的{​​{1}},如下所示:

lval_add

希望这会有所帮助!

答案 2 :(得分:0)

参数类型不匹配:不兼容的指针类型“ lval *”和“结构匿名:: lval *”。

以上警告是因为您具有匿名结构。尝试:

typedef struct lval {
    int type;
    union expr value;
};

这至少可以解决此警告。