简体   繁体   English

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

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

I'm reasonably certain that I have a horrible understanding of pointers in C (at least syntactically). 我可以肯定地说,我对C中的指针有一个可怕的了解(至少在语法上)。

I am trying to have a struct which is a linkedlist with a bunch of data. 我试图有一个结构,它是带有大量数据的链表。 Later, I try to add a new struct as the head of that linkedlist, pointing to the old head, which has a "prior" link to the new head. 稍后,我尝试添加一个新结构作为该链表的头,指向旧头,该旧头具有指向新头的“先前”链接。

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++;
}

And I am getting these errors: 我收到这些错误:

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;

RCB and struct RCB are two completely different, unrelated types. RCBstruct RCB是两种完全不同的,无关的类型。 struct RCB is never defined in your code and is hence incomplete. struct RCB从未在您的代码中定义,因此不完整。

To make them one and the same, write 为了使它们相同,写

typedef struct RCB {
   ....
} RCB;

This is one part of the problem. 这是问题的一部分。

Don't use *RRhead when initializing new_rcb . 初始化new_rcb时不要使用*RRhead new_rcb You just want RRhead . 您只需要RRhead

The struct has a pointer, ie struct RCB *prior so you must use the pointer RRhead . 该结构具有一个指针,即struct RCB *prior因此您必须使用指针RRhead

firstly, RRhead is just a pointer, so when you go RRhead->prior, you will get a runtime error, because RRhead isn't pointing to anything (RRhead->prior says "get the 'prior'property of the RCB struct that RRhead is pointing to) 首先,RRhead只是一个指针,所以当您转到RRhead-> prior时,会遇到运行时错误,因为RRhead没有指向任何内容(RRhead-> prior说“获取RCB结构的'优先'属性, RRhead指向)

secondly, when you pass *RRhead as the last initializer of new_rcb: prior is an RCB pointer, and RRhead is an RCB pointer. 其次,当您传递* RRhead作为new_rcb的最后一个初始化程序时:Prior是RCB指针,而RRhead是RCB指针。 they are the same type, so there is no need to do any referencing or dereferencing, just pass RRhead. 它们是同一类型,因此无需进行任何引用或取消引用,只需传递RRhead。 this will make the prior property of new_rcb point to whatever RRhead is pointing to at the time (which is nothing at that moment, because RRhead hasn't been initalized to any value) 这将使new_rcb的先前属性指向当时RRhead指向的内容(当时不存在,因为RRhead尚未初始化为任何值)

thirdly, RRhead->prior = new_rcb; 第三,RRhead-> prior = new_rcb; is wrong because 'prior' is an RCB pointer, whereas new_rcb is not a pointer, it is a RCB. 这是错误的,因为'prior'是RCB指针,而new_rcb不是指针,而是RCB。 to pass the adress of new_rcb, go RRhead->prior = &new_rcb; 要传递new_rcb的地址,请转到RRhead-> prior =&new_rcb;

Finally, its unlikely you will want new_rcb to be statically allocated. 最后,不太可能需要静态分配new_rcb。

There are lots of problems here. 这里有很多问题。 It's not clear exactly what your real code is since you keep changing it but I'll have a crack: 由于您不断更改它,因此尚不清楚您的真实代码是什么,但我会遇到一个困难:


First of all, in C, struct tags are in a separate "namespace" to typedef names. 首先,在C语言中,结构标记位于单独的“命名空间”中,以键入typedef名称。 There is no relation between struct RCB and RCB . struct RCBRCB之间没有关系。 Particularly, in this code: 特别是在此代码中:

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

next does NOT point to a RCB . next不指向RCB It points to a struct RCB which is a completely different type to RCB . 它指向的struct RCBRCB完全不同。 This is why you get the error error: dereferencing pointer to incomplete type . 这就是为什么出现错误error: dereferencing pointer to incomplete type You never defined what struct RCB is. 您从未定义过struct RCB

If you want a struct containing pointers to itself, you must use a struct tag, because the typedef name does not exist until the typedef is complete. 如果要包含指向其自身的指针的结构,则必须使用struct标记,因为在完成typedef之前,typedef名称不存在。 For example: 例如:

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

typedef struct RCB RCB;

Of course, the typedef is optional; 当然,typedef是可选的; and could be combined with the struct definition but I think it is clearer to separate the two. 可以与struct定义结合使用,但我认为将两者分开更清晰。


The next problem is: 下一个问题是:

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

This is not allowed in C, the right-hand side of the assignment operator must be an expression. 在C语言中不允许这样做,赋值运算符的右侧必须是一个表达式。 A brace-enclosed list is not an expression. 用大括号括起来的列表不是表达式。 The simplest way to avoid this problem is to use initialization: 避免此问题的最简单方法是使用初始化:

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

Another runtime problem is hinted at in the latest edit: 最新的编辑提示了另一个运行时问题:

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++;
}

Obviously this is some sort of pseudocode. 显然,这是某种伪代码。 But new_rcb is a local variable to the blah function. 但是new_rcbblah函数的局部变量。 new_rcb stops existing when blah returns. blah返回时, new_rcb停止存在。 This means the list pointed to by RRhead will contain a dangling pointer. 这意味着RRhead指向的列表将包含一个悬空指针。

When using pointers you need to have a very clear mental image of where pointers are pointing and what the lifetime is of the objects being pointed to. 使用指针时,您需要非常清楚地了解指针指向的位置以及所指向的对象的寿命。

To fix this you could either use dynamic allocation ( malloc ), or some sort of memory pool. 要解决此问题,您可以使用动态分配( malloc )或某种内存池。

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

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