繁体   English   中英

C-重新分配指针,它是struct的属性:将指针解引用为不完整类型

[英]C - reassigning pointer which is attribute of struct: dereferencing pointer to incomplete type

我可以肯定地说,我对C中的指针有一个可怕的了解(至少在语法上)。

我试图有一个结构,它是带有大量数据的链表。 稍后,我尝试添加一个新结构作为该链表的头,指向旧头,该旧头具有指向新头的“先前”链接。

typedef struct{
  int sequence_number;
  int file_descriptor;
  FILE *requested_file;
  int bytes_remaining;
  int quantum;
  struct RCB *next;
  struct RCB *prior;
} RCB;

   RCB *RRhead;
...


function blah(){
  RCB new_rcb = {sequence_counter, fd, fin, new_bytes_remaining, new_quantum, RRhead, NULL};
  RRhead->prior = &new_rcb;
  RRhead = &new_rcb;
  sequence_counter++;
}

我收到这些错误:

sws.c: In function ‘admit_to_scheduler_RR’:
sws.c:317:3: warning: initialization from incompatible pointer type [enabled by default]
   RCB new_rcb = {sequence_counter, fd, fin, new_bytes_remaining, new_quantum, RRhead, NULL};
sws.c:317:3: warning: (near initialization for ‘new_rcb.next’) [enabled by default]
sws.c:318:17: warning: assignment from incompatible pointer type [enabled by default]
   RRhead->prior = &new_rcb;

RCBstruct RCB是两种完全不同的,无关的类型。 struct RCB从未在您的代码中定义,因此不完整。

为了使它们相同,写

typedef struct RCB {
   ....
} RCB;

这是问题的一部分。

初始化new_rcb时不要使用*RRhead new_rcb 您只需要RRhead

该结构具有一个指针,即struct RCB *prior因此您必须使用指针RRhead

首先,RRhead只是一个指针,所以当您转到RRhead-> prior时,会遇到运行时错误,因为RRhead没有指向任何内容(RRhead-> prior说“获取RCB结构的'优先'属性, RRhead指向)

其次,当您传递* RRhead作为new_rcb的最后一个初始化程序时:Prior是RCB指针,而RRhead是RCB指针。 它们是同一类型,因此无需进行任何引用或取消引用,只需传递RRhead。 这将使new_rcb的先前属性指向当时RRhead指向的内容(当时不存在,因为RRhead尚未初始化为任何值)

第三,RRhead-> prior = new_rcb; 这是错误的,因为'prior'是RCB指针,而new_rcb不是指针,而是RCB。 要传递new_rcb的地址,请转到RRhead-> prior =&new_rcb;

最后,不太可能需要静态分配new_rcb。

这里有很多问题。 由于您不断更改它,因此尚不清楚您的真实代码是什么,但我会遇到一个困难:


首先,在C语言中,结构标记位于单独的“命名空间”中,以键入typedef名称。 struct RCBRCB之间没有关系。 特别是在此代码中:

typedef struct {
  struct RCB *next;
  struct RCB *prior;
} RCB;

next不指向RCB 它指向的struct RCBRCB完全不同。 这就是为什么出现错误error: dereferencing pointer to incomplete type 您从未定义过struct RCB

如果要包含指向其自身的指针的结构,则必须使用struct标记,因为在完成typedef之前,typedef名称不存在。 例如:

struct RCB
{
    // ...
    struct RCB *next, *prior;
};

typedef struct RCB RCB;

当然,typedef是可选的; 可以与struct定义结合使用,但我认为将两者分开更清晰。


下一个问题是:

new_rcb = {sequence_counter, fd, fin, new_bytes_remaining, new_quantum, RRhead, NULL};

在C语言中不允许这样做,赋值运算符的右侧必须是一个表达式。 用大括号括起来的列表不是表达式。 避免此问题的最简单方法是使用初始化:

RCB new_rcb = {sequence_counter, fd, fin, new_bytes_remaining, new_quantum, RRhead, NULL};

最新的编辑提示了另一个运行时问题:

function blah(){
  RCB new_rcb = {sequence_counter, fd, fin, new_bytes_remaining,  new_quantum, RRhead, NULL};
  RRhead->prior = &new_rcb;
  RRhead = &new_rcb;
  sequence_counter++;
}

显然,这是某种伪代码。 但是new_rcbblah函数的局部变量。 blah返回时, new_rcb停止存在。 这意味着RRhead指向的列表将包含一个悬空指针。

使用指针时,您需要非常清楚地了解指针指向的位置以及所指向的对象的寿命。

要解决此问题,您可以使用动态分配( malloc )或某种内存池。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM