【问题标题】:Nested pointer to struct containing pointer to containing struct?指向包含指向包含结构的指针的结构的嵌套指针?
【发布时间】:2018-07-23 08:23:01
【问题描述】:

首先,我有一个结构:

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 *' 和 'struct anonymous::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);
}

【问题讨论】:

  • I ignored the warning and complied it successfully...所有问题的根源。
  • 除了警告之外,lval_del 真的是递归的吗?如果是,您认为递归应该在运行时何时停止?
  • 你忘了预先声明struct lval;吗?
  • 这两个结构是递归的,但我尝试你的方法作为添加结构 lval;在 sexpr 之前,然后在 lval* 下面编辑为 struct lval*,它仍然会崩溃。可能我没有得到你真正的意思,希望你能把你的代码拿出来。
  • 你想用这段代码实现什么数据结构? cell 真的需要成为 lval ** 吗?

标签: c pointers struct unions double-pointer


【解决方案1】:

struct lval** cell; 无效,你没有struct lval,你typedefed 一个匿名结构到lval

改成lval **cell;

您也不要在 add 函数中增加 v-&gt;value.sexpr1-&gt;count,因此它总是会写入相同的位置。

【讨论】:

  • 不行。修改后编译器不会旋转**cell之前的lval。
  • 抱歉,我没有显示完整的代码来突出问题。我正确地增加了计数。
  • 如我所见,这是一个类型错误。如果您认为不同,我可以发布我的完整代码。
【解决方案2】:

这里的问题在于 realloc。您正在尝试重新分配从未分配过的内存。此外,在v-&gt;value.sexpr1-&gt;cell等表达式中使用之前,您需要为sexpr1分配内存

试试这个:

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_addlval,如下所示:

lval *z = malloc(sizeof(lval));
z->value.sexpr1 = malloc(sizeof(sexpr));
z->value.sexpr1->cell= NULL;

希望这会有所帮助!

【讨论】:

  • realloc(NULL,size);malloc(size); 相同。
  • 哦,是的...我们也可以使用它。但在这种情况下,指针必须是真正的 NULL。看看你是否在这种情况下正确初始化。
【解决方案3】:

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

上面的警告是因为你有一个匿名结构。试试:

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

这至少应该解决这个警告。

【讨论】:

  • 我试过了,但是不行。我还需要用你的方式改变这些结构/联合的def顺序吗?
猜你喜欢
  • 1970-01-01
  • 2018-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-30
  • 2010-11-14
  • 2016-08-28
相关资源
最近更新 更多