2012-11-04 33 views
3

作爲我爲大學課程做的任務的一部分,我需要在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->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; 
} 

其中ProcessState被定義爲:

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

是的,過程是:

typedef process_Struct* Process 

仿真聲明:

//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)其中:

typedef simulation* Simulation; 

runSimulation在Simulation.c聲明

確切的錯誤信息爲:源極/ Simulation.c:154:50:錯誤:解引用指針不完全型 這就是爲什麼這個被證明是很討厭,它並沒有給出更多的信息,即使使用-verbose,-g和其他一些調試標誌。

我意識到我不應該用typdef指針,但是,愚蠢的是,教授把它作爲任務的要求。引用: 「如果可能,請使用typedef定義指向結構體的指針,這樣TA就可以更輕鬆地讀取仿真代碼。」 我非常惱火,因爲這是一個可怕的想法,助教應該能夠讀取代碼。

+0

你可以發佈listPushBack的代碼嗎? –

+0

是否將'Process'類型定義爲指針? –

+0

我們需要查看您的模擬類型定義(以及它如何包含在具有違規行的文件中)。 – CrazyCasta

回答

2

您的意見建議您在history.c中定義struct record源文件。如果您在任何其他源文件中使用struct record,那麼您應該在history.h中定義它,否則當您嘗試在另一個文件中使用指向struct record的指針時,您會得到此確切錯誤。

+0

我試着將'struct process_struct'移動到Process.h中,編譯器停止抱怨,開始抱怨'struct record'。我瀏覽了所有代碼並做了相同的更改。現在編譯沒有任何問題。 –

1

你遇到的問題是什麼類型的SIM是一個指針沒有定義。它被聲明(這是你如何聲明一個指針),但沒有定義。換句話說,你可能做過類似:

struct Simulation; 

void myFunc() { 
    struct Simulation* sim; 
    sim->history; 
} 

哪裏sim->history是在您的通話listPushBack做SIM史上成員的間接引用。

2

當你只有前向聲明的東西然後去使用它時,你通常會看到這個錯誤。IE如果你有:

// foo.h 
struct Process; 

// foo.c 
#include "foo.h" 
Process* foo; 
std::cout << foo->i 

你會得到一個關於derefencing一個不完整的類型的指針錯誤。這可能是當你在這一行提領P/SIM卡所發生的事情:

listPushBack(sim->history, (void*)newRecord(p->pid, sim->currentTime, old, p->state)); 

的解決方案是,確保你已經#include倒是的Process的完整定義,即添加的#include「 Process.h「上面代碼中的某處。

+0

首先,這是C,而不是C++,所以沒有類。我已經在Simulation.c中包含了Process.h。 –

相關問題