C - 重新分配作为结构属性的指针:取消引用不完整类型的指针
C - reassigning pointer which is attribute of struct: dereferencing pointer to incomplete type
我相当确定我对 C 中的指针的理解很糟糕(至少在语法上)。
我正在尝试创建一个包含大量数据的 linkedlist 结构。后来,我尝试添加一个新结构作为那个 linkedlist 的头部,指向旧头部,它有一个 "prior" link 指向新头部。
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;
这是问题的一部分。
初始化 new_rcb
时不要使用 *RRhead
。你只想要 RRhead
.
该结构有一个指针,即 struct RCB *prior
所以你必须使用指针 RRhead
。
首先,RRhead 只是一个指针,所以当你进入 RRhead->prior 时,你会得到一个运行时错误,因为 RRhead 没有指向任何东西(RRhead->prior 说“获取 'prior'属性 RRhead 指向的 RCB 结构)
其次,当你将*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 被静态分配。
RCB
和struct RCB
是两种完全不同的、不相关的类型。 struct RCB
从未在您的代码中定义,因此不完整。
要使它们合二为一,写
typedef struct RCB {
....
} RCB;
这里有很多问题。由于您一直在更改它,所以不清楚您的真实代码到底是什么,但我会破解的:
首先,在 C 语言中,struct 标签在一个单独的 "namespace" 到 typedef 名称中。 struct RCB
和 RCB
之间没有关系。特别是,在这段代码中:
typedef struct {
struct RCB *next;
struct RCB *prior;
} RCB;
next
不指向 RCB
。它指向一个 struct RCB
,它是一个与 RCB
完全不同的类型。这就是您收到错误 error: dereferencing pointer to incomplete type
的原因。您从未定义 struct RCB
是什么。
如果您想要一个包含指向自身的指针的结构,您必须使用结构标记,因为在 typedef 完成之前 typedef 名称不存在。例如:
struct RCB
{
// ...
struct RCB *next, *prior;
};
typedef struct RCB RCB;
当然,typedef 是可选的; 可以与结构定义结合,但我认为将两者分开更清楚。
下一个问题是:
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_rcb
是 blah
函数的局部变量。 new_rcb
在 blah
returns 时停止存在。这意味着 RRhead
指向的列表将包含一个悬挂指针。
使用指针时,您需要非常清楚地了解指针指向的位置以及所指向对象的生命周期。
要解决此问题,您可以使用动态分配 (malloc
) 或某种内存池。
我相当确定我对 C 中的指针的理解很糟糕(至少在语法上)。
我正在尝试创建一个包含大量数据的 linkedlist 结构。后来,我尝试添加一个新结构作为那个 linkedlist 的头部,指向旧头部,它有一个 "prior" link 指向新头部。
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;
这是问题的一部分。
初始化 new_rcb
时不要使用 *RRhead
。你只想要 RRhead
.
该结构有一个指针,即 struct RCB *prior
所以你必须使用指针 RRhead
。
首先,RRhead 只是一个指针,所以当你进入 RRhead->prior 时,你会得到一个运行时错误,因为 RRhead 没有指向任何东西(RRhead->prior 说“获取 'prior'属性 RRhead 指向的 RCB 结构)
其次,当你将*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 被静态分配。
RCB
和struct RCB
是两种完全不同的、不相关的类型。 struct RCB
从未在您的代码中定义,因此不完整。
要使它们合二为一,写
typedef struct RCB {
....
} RCB;
这里有很多问题。由于您一直在更改它,所以不清楚您的真实代码到底是什么,但我会破解的:
首先,在 C 语言中,struct 标签在一个单独的 "namespace" 到 typedef 名称中。 struct RCB
和 RCB
之间没有关系。特别是,在这段代码中:
typedef struct {
struct RCB *next;
struct RCB *prior;
} RCB;
next
不指向 RCB
。它指向一个 struct RCB
,它是一个与 RCB
完全不同的类型。这就是您收到错误 error: dereferencing pointer to incomplete type
的原因。您从未定义 struct RCB
是什么。
如果您想要一个包含指向自身的指针的结构,您必须使用结构标记,因为在 typedef 完成之前 typedef 名称不存在。例如:
struct RCB
{
// ...
struct RCB *next, *prior;
};
typedef struct RCB RCB;
当然,typedef 是可选的; 可以与结构定义结合,但我认为将两者分开更清楚。
下一个问题是:
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_rcb
是 blah
函数的局部变量。 new_rcb
在 blah
returns 时停止存在。这意味着 RRhead
指向的列表将包含一个悬挂指针。
使用指针时,您需要非常清楚地了解指针指向的位置以及所指向对象的生命周期。
要解决此问题,您可以使用动态分配 (malloc
) 或某种内存池。