2013-09-26 41 views
0

我與這兩個結構的工作返回一個列表節點相隔一個鏈表,第一個擁有員工信息,而第二個保存的列表信息:功能在C

typedef struct ListNodeTag{ 
    int idNumber; 
    struct ListNodeTag *next; 
} Employee; 

typedef Employee Item; 

typedef struct { 
    int size; 
    Item *head; 
} List; 

我已經調用此函數我在其中發送一個位置,列表的頭部,以及一個指向員工以外的元素的指針。

void Peek (int position, List *L, Item *X) { 

    int i; 
    Item *currentPtr; 

    currentPtr = L->head; 

    for(i = 0; i < position; i++){ 
    if(currentPtr->next == NULL){ 
     X = currentPtr; 
     break; 
    } 
    currentPtr = currentPtr->next; 
    } 

    X = currentPtr; 

} 

我在這個循環中調用了從主函數Peek。

for(i=0;i<Length(&L);i++){ 
    Peek(i,&L,&S); 
    printf(" %d%\n",idNumber); 
    } 

它的目的是打印列表中的每個成員與僱員ID在一個新的行。該列表的第一部件然而,當第二被調用時,一個SEG-故障發生在線路currentPtr = currentPtr->next;

我的列表中的數據是從該插入功能填充:

void Insert (Item X, int position, List *L) { 
    int i; 
    Item *currentPtr,*previousPtr; 
    Item *temp = malloc(sizeof(Item)); 

    temp->idNumber = X.idNumber; 
    temp->next = NULL; 

    previousPtr = NULL; 

    if(L->head == NULL){ 
    L->head = temp; 
    } 

    else{ 
    currentPtr = L->head; 
    for(i=0;i<=position && currentPtr!=NULL;i++){ 
     previousPtr = currentPtr; 
     currentPtr = currentPtr->next; 
    } 
    temp->next = currentPtr; 
    previousPtr->next = temp; 
    } 
    L->size +=1; 
} 

一旦印刷,我我能夠在沒有segfault的情況下獲得結果,但是,無論列表是多長時間,它都會重複相同的條目。 EG:長度爲3我得到:

10925 
10925 
10925 
+0

你有一個'for'循環去每個'next'的位置。但是你沒有檢查是否碰到了「next」,它是NULL。但是,這裏有很多代碼缺失,所以很難說出你是如何填充數據的。 – lurker

+0

我已添加我的插入功能以獲取更多詳細信息。如果它命中NULL,那麼我認爲它應該自動中止以避免seg-fault? – user2225940

+0

它會如何「自動」中止?如果它引用NULL作爲下一個指針,它將會出現段錯誤。因此,想象一下在循環迭代中,'currentPtr-> next'的值爲NULL的情況。然後,下一個'currentPtr'的值由賦值變爲NULL。然後下一次循環嘗試,本質上,'NULL-> next'將會出現段錯誤。 – lurker

回答

0

該代碼至少有兩個問題。


第一個問題是您的Peek函數。看的最後一行:

X = currentPtr; 

回想一下,C是一個call by value語言,這意味着該線路僅改變的Peek本地的X值,其被簡單地丟棄時Peek返回; main從來沒有看到它。

您需要更改Peek是像

void Peek (int position, List *L, Item **X) { 

,然後的Peek最後一行應改爲

*X = currentPtr; 

因此,您需要更改作爲傳遞的值Xmain分成Peek。你沒有說你怎麼申報Smain功能裏面,但我相信它是目前的形式:

Item *S; 

然後,您需要將其更改爲

Item *S[1]; 

Peek調用可以單獨留下作爲

Peek(i,&L,&S); 

這些更改之後,main將宣佈長度1的陣列SItem指針,並且會將S的地址傳遞給PeekPeek的最後一行然後將currentPtr存儲在由其值X指向的地址處,寫入數組S中的第一個Item指針。


第二個問題是與for循環:

for(i=0;i<Length(&L);i++){ 
    Peek(i,&L,&S); 
    printf(" %d%\n",idNumber); 
} 

你爲什麼想到printf對每次循環打印不同的東西?在循環中,idNumber沒有被改變!在Peek的(固定)版本中,唯一要更改的是數組S的第一個元素,所以您需要諸如printf("%d\n", S[0]->idNumber);之類的東西。


你也應該從你的Peek循環刪除X = currentPtr;

if(currentPtr->next == NULL){ 
    X = currentPtr; 
    break; 
} 

,因爲它是多餘的;在break聲明之後立即運行完全相同的行(在未修改的Peek中)。