2013-09-26 34 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中)。