C 无法找到“的源”;取消引用指向不完整类型的指针“;错误
作为我大学课程作业的一部分,我需要用C(而不是C++)编写一个CPU调度模拟器。我在使用GCC编译时遇到了一个问题,它给了我几个关于“取消引用指向不完整类型的指针”的错误。所有的错误都是同一个代码的结果,这让我觉得代码有问题 违规代码是:C 无法找到“的源”;取消引用指向不完整类型的指针“;错误,c,pointers,gcc,compiler-errors,dereference,C,Pointers,Gcc,Compiler Errors,Dereference,作为我大学课程作业的一部分,我需要用C(而不是C++)编写一个CPU调度模拟器。我在使用GCC编译时遇到了一个问题,它给了我几个关于“取消引用指向不完整类型的指针”的错误。所有的错误都是同一个代码的结果,这让我觉得代码有问题 违规代码是: //Push a record of this state change to the back of the simulation's history list listPushBack(sim->history, (void*)newRecord(p
//Push a record of this state change to the back of the simulation's history list
listPushBack(sim->history, (void*)newRecord(p->pid, sim->currentTime, wait, ready));
这与跟踪模拟的历史有关,以便稍后进行分析。记录定义为:
//History.h
typedef struct record* Record;
//History.c
typedef struct record recordType;
struct record{
long time;
int pid;
State oldState;
State newState;
};
Record newRecord(int pid, long time, ProcessState oldState, ProcessState newState){
Record r = (Record)malloc(sizeof(recordType));
if(r == NULL){
fprintf(stderr, "History.c:newRecord:Failed to allocate memory for new Record\n");
//This is serious, abort execution
exit(-1)
}
r->time = time;
r->pid = pid;
r->oldState = oldState;
r->newState = newState;
return r;
}
//Process.h
typedef enum process_state ProcessState;
enum process_state{
arrive = 0,
ready = 1,
run = 2,
wait = 3,
done = 4
};
其中ProcessState定义为:
//History.h
typedef struct record* Record;
//History.c
typedef struct record recordType;
struct record{
long time;
int pid;
State oldState;
State newState;
};
Record newRecord(int pid, long time, ProcessState oldState, ProcessState newState){
Record r = (Record)malloc(sizeof(recordType));
if(r == NULL){
fprintf(stderr, "History.c:newRecord:Failed to allocate memory for new Record\n");
//This is serious, abort execution
exit(-1)
}
r->time = time;
r->pid = pid;
r->oldState = oldState;
r->newState = newState;
return r;
}
//Process.h
typedef enum process_state ProcessState;
enum process_state{
arrive = 0,
ready = 1,
run = 2,
wait = 3,
done = 4
};
我玩了一下,得到了同样的错误:
Process p = (Process)listGetAt(sim->waitingQueue, i);
ProcessState old = p->state;
listPushBack(sim->history, (void*)newRecord(p->pid, sim->currentTime, old, p->state));
谢天谢地,这不是一个星期到期,所以我有时间玩,但我希望有人能给我指出正确的方向,以免我浪费太多时间搞砸事情
编辑:按评论中出现的顺序回答问题
//DoubleLinkList.c
bool listPushBack(DoubleList l, void* data){
return listInsert(l, data, -1);
}
bool listInsert(DoubleList l, void* data, int pos){
int index = pos;
//If value is negative, convert to a index relative to the end of the list
if(index < 0){
index = listSize(l) + index + 1;
}
//Check index bounds
if(index > listSize(l) || index < 0){
fprintf(stderr, "DoubleLinkList.c:listInsert:Insert index %i out of bounds\n", pos);
//This is not serious enough to warrent an abort
return false;
}
//Data is null
if(data == NULL){
fprintf(stderr, "DoubleLinkList.c:listInsert:Data value for doubly linked list node cannot be NULL\n");
//This is not serious enough to warrent an abort
return false;
}
Node insertNode = newNode(data);
//Case: End of list
if(index == listSize(l)){
l->tail->next = insertNode;
insertNode->prev = l->tail;
l->tail = insertNode;
l->size++;
return true;
}
//Case: Start of list
else if(index == 0){
l->head->prev = insertNode;
insertNode->next = l->head;
l->head = insertNode;
l->size++;
return true;
}
//Case: Middle of list
Node node = l->head;
//Scan through list to reach index pos
int i;
for(i = 0; i < index; i++){
if(node == NULL){
fprintf(stderr, "DoubleLinkList.c:listGetPosition:NULL encoutered unexpectedly while traversing doubly linked list at index %i\n", i);
//This is a serious problem, abort execution
exit(-1);
}
node = node->next;
}
//Insert before Node at index pos
insertNode->next = node;
insertNode->prev = node->prev;
node->prev->next = insertNode;
node->prev = insertNode;
l->size++;
return true;
}
模拟声明:
//Simulation.c
struct simulation{
SimType type;
long currentTime;
unsigned int totalProcesses;
DoubleList arriveQueue;
DoubleList readyQueue;
DoubleList waitingQueue;
DoubleList doneQueue;
Process running;
DoubleList history;
};
引发问题的方法是runSimulation(Simulation sim),其中:
runSimulation在Simulation.c中声明
确切的错误消息是:source/Simulation.c:154:50:错误:取消引用指向不完整类型的指针
这就是为什么它如此令人讨厌的原因,它没有提供更多的信息,即使使用-verbose,-g和其他一些调试标志
我意识到我不应该输入指针,但是,愚蠢的是,教授把它作为作业的一项要求。引述:
如果可能,请使用typedef定义指向结构的指针。这样,TA可以更轻松地读取模拟代码
我对此非常恼火,因为这是一个糟糕的想法,助教应该能够阅读代码。您遇到的问题是没有定义sim所指向的任何类型。它已声明(这是您可以声明指向它的指针的方式),但未定义。换言之,您可能做过如下工作:
struct Simulation;
void myFunc() {
struct Simulation* sim;
sim->history;
}
其中,
sim->history
是在listPushBack呼叫中取消对sim历史成员的引用。当您只向前声明某个内容,然后使用它时,通常会看到此错误。即如果你有:
// foo.h
struct Process;
// foo.c
#include "foo.h"
Process* foo;
std::cout << foo->i
解决方案是确保您已经在上面的代码中添加了
(包含进程的完整定义
),即在上面的代码中添加(包含“Process.h”)。您的评论表明您正在历史.c源文件中定义结构记录
。如果在任何其他源文件中使用结构记录
,则应在history.h中定义它,否则,当您尝试在另一个文件中使用指向struct record
的指针时,您将得到这个准确的错误。您可以发布listPushBack的代码吗?Process
typedef是否指向指针?我们需要查看您的模拟类型定义(以及它是如何包含在有违规行的文件中的)。请剪切/粘贴准确的错误消息-这肯定会有帮助。但是我同意你的观点,不,问题很可能是“结构记录”应该在“history.h”中定义,而不是在“history.c”中定义。不要使用TyPulf指针:你只会混淆你自己。首先,这是C,不是C++,所以没有类。我已经在模拟中包含了Process.h。c.我尝试将struct Process\u struct
移动到Process.h中,编译器停止对此抱怨,开始抱怨struct record
。我检查了所有代码并做了相同的更改。它现在编译起来没有任何问题。
listPushBack(sim->history, (void*)newRecord(p->pid, sim->currentTime, old, p->state));