2009-05-06 74 views
0

值作爲轉讓的一部分,我需要寫兩個函數:打印刪除從我的鏈表

  1. 凝聚了表示爲鏈表
  2. 一個函數的兩個自然數的函數打印以相同方式表示的數字。

由於某些原因,這兩個函數都能夠單獨完美地工作,但是當我試圖在sum函數的結果上使用print函數時,它會在打印函數的開始處改變右值的總和,並打印錯誤的值。當我使用printf在main中打印相同的值時,沒有任何問題。我的代碼在下面詳細介紹。有任何想法嗎?

void main() 
{ 
    int a[1] = { 1 }, 
    b[1] = { 2 }; 
    int * *pa, **pb; 
    List lst1, lst2; 
    List sum; 

    pa = (int * *) malloc(sizeof(int *)); * pa = &a[0]; 
    pb = (int * *) malloc(sizeof(int *)); * pb = &b[0]; 
    lst1 = arrToList(pa, 1); 
    lst2 = arrToList(pb, 1); 
    addNumbers(lst1, lst2, &sum); 
    //printf("%d\n",*(sum.head->dataPtr)); 
    printNumber(sum); 
} 

//a function that recieves a number represented ad a list and prints it 
void printNumber(List num) 
{ 
    ListNode * curr; 
    int currData, 
    i, 
    number; 

    if (isEmptyList(num) == TRUE) 
    printf("the input was an empty list, nothing to print"); 
    else 
    { 
    i = 0; 
    number = 0; 
    curr = num.head; 
    while (curr != NULL) 
    { 
     currData = *(curr - >dataPtr); 
     number = number + currData * ((int) pow(10, i)); 
     curr = curr - >next; 
     i++; 
    } 
    printf("%d \n", number); 
    } 
} 

// a function that sums in list 
// representation two numbers, 
// each represented as a list 
void addNumbers(List n1, List n2, List * sum) 
{ 
    ListNode * currN1; 
    ListNode * currN2; 
    ListNode * currSum; 
    int currN1N2Sum; //stores the sum of the current digits in n1 and n2 
    int carrier, 
    prevCarrier; //current and previous carriers that carries +1 to the 
    next digit of sum 
    if the lst sum was bigger then 9 

    if ((isEmptyList(n1) == TRUE) || (isEmptyList(n2) == TRUE)) 
    printf("bad input =("); 
    else 
    { 
    currN1 = n1.head; 
    currN2 = n2.head; * sum = createEmptyList(); 
    carrier = 0; 
    prevCarrier = 0; 
    while ((currN1 != NULL) && (currN2 != NULL)) 
    { 
     currN1N2Sum = *(currN1->dataPtr) + *(currN2->dataPtr) + prevCarrier; 
     if (currN1N2Sum > 9) 
     { 
     carrier = 1; 
     currN1N2Sum = currN1N2Sum - 10; 
     } 
     currSum = creatNewListNode(& currN1N2Sum, NULL); 
     insertNodeToEnd(sum, currSum); 
     prevCarrier = carrier; 
     carrier = 0; 
     currN1 = currN1 - >next; 
     currN2 = currN2 - >next; 
    } //while ((currL1!=NULL)&&(currL2!=NULL)) 

    while (currN1 != NULL) 
    { 
     currN1N2Sum = *(currN1 - >dataPtr) + prevCarrier; 
     currN1 = currN1 - >next; 
     if (prevCarrier != 0) prevCarrier = 0; 
    } 

    while (currN2 != NULL) 
    { 
     currN1N2Sum = *(currN2 - >dataPtr) + prevCarrier; 
     currN2 = currN2 - >next; 
     if (prevCarrier != 0) prevCarrier = 0; 
    } 
    } // ! ((isEmptyList(n1)==TRUE)||(isEmptyList(n2)==TRUE)) 
} 

這裏是代碼的其餘部分:

typedef struct listNode{ 
int* dataPtr; 
struct listNode* next; 
} ListNode; 

typedef struct list 
{ 
ListNode* head; 
ListNode* tail; 
} List; 

List createEmptyList()//creates and returns an empty linked list 
{ 
    List res; 

    res.head = res.tail = NULL; 

    return res; 
} 

Bool isEmptyList (List lst)//checks if a given list is empty or not 
{ 
    if (lst.head == NULL && lst.tail == NULL) 
     return TRUE; 
    else 
     return FALSE; 
} 

void insertDataToEnd (List * lst, int *dataPtr) //inserts new data to the end of an existing linked list 
{ 
    ListNode * newTail; 
    newTail = creatNewListNode (dataPtr, NULL); 
    insertNodeToEnd(lst,newTail); 
} 

void insertNodeToEnd (List * lst, ListNode * newTail)//insert an existing node to an existing linked list 
{ 
    if (isEmptyList(*lst) == TRUE) 
     insertNodeToStart (lst,newTail); 
    else 
    { 
     (*lst).tail -> next = newTail; 
     newTail->next = NULL; 
     (*lst).tail = newTail; 
    } 
} 


ListNode * creatNewListNode (int * dataPtr, ListNode * next)//inserts new node in an existing linked list 
{ 
    ListNode * res; 

    res = (ListNode *) malloc (sizeof(ListNode)); 

    res -> dataPtr = dataPtr; 
    res -> next  = next; 

    return res; 
} 

void insertNodeToStart (List * lst, ListNode * newHead)//inserts node to the begining of a given linked list 
{ 
    if (isEmptyList(*lst) == TRUE) 
    { 
     (*lst).head = newHead; 
     (*lst).tail = newHead; 
     newHead -> next = NULL; 
    } 
    else 
    { 
     newHead -> next = (*lst).head; 
     (*lst).head = newHead; 
    } 
} 
+0

當添加2 + 1時,你會得到什麼輸出?你說什麼「改變」? – ParoXoN 2009-05-06 17:18:20

+0

你的代碼很難編譯。沒有稱爲Bool的類型,或arrToList的定義。 – dirkgently 2009-05-06 17:53:57

回答

5

bug是在功能的addNumbers。 當您添加一個節點來存儲總和時,您將一個指針傳遞給作爲本地變量(存儲在堆棧中)的變量currN1N2Sum。當addNumbers函數終止時,局部變量的存儲空間被設置爲空閒。在該位置找到的值將保持不變,因此只要存儲未被重用,該值顯然是有效的。

這就是爲什麼你有印象addNumbers功能是正確的。當調用printNumber函數時,存儲將被覆蓋,並在那裏找到不同的值。

這解釋了你的錯誤。

addNumbers還有另一個問題。當您嘗試添加兩位數字時,currN1N2Sum的內容將被新值覆蓋。

你應該做的是分配一個緩衝區(malloc)並將包含在currN1N2Sum中的值存儲到它中。將指針傳遞給緩衝區到新節點中。

順便說一句:你可能會改變(* lst)。頭在lst->頭。它會使你的代碼更具可讀性。

0

我們需要看到更多的代碼:你如何定義的數據保持節點結構,如何添加節點等

以下行是可疑的:

number=number+currData*((int)pow(10,i)); 

說,你有123存儲爲1,2,和3個節點:

number = 0; 
    number = 0 + 1 * 1 = 1; 
    number = 1 + 2 * 10 = 21; 
    number = 21 + 3 * 100 = 321; 

但是,如果你保存是3,2,1個節點上,您會得到:

number = 0; 
    number = 0 + 3 * 1 = 3; 
    number = 3 + 2 * 10 = 23; 
    number = 23 + 1 * 100 = 123; 

這是你的問題?

+0

問題是,通過調試,我知道該值在函數的開頭就已經丟失,甚至在行之前: if(isEmptyList(num)== TRUE) – Lior 2009-05-06 17:13:59

+0

向我們展示List的定義,整個代碼。 – dirkgently 2009-05-06 17:16:29

0

我不是,如果這是沒有看到的createNewListNode()執行情況的問題或沒有,但這裏的一些思考:
哪裏dataPtr S IN的sum列表指點你從addNumbers()調用返回後?

+0

dataPtr從addnumbers()返回後指向0x0012fdf4。它在進入打印功能時指向相同的地址,但是該值更改爲-858993460,並且currData,i和數字具有相同的值。 – Lior 2009-05-06 17:32:22

0

我覺得你可能會把事情弄亂了......你在addNumbers中分配列表'sum'的方式似乎很奇怪。 (我如果它打破東西也不會感到驚訝...)

嘗試做了這些改變:

在主:

List *sum; 
<...> 
addNumbers(lst1,lst2,sum); //Note the absence of the reference operator & 
printNumbers(*sum); 

(或者,改變printNumbers接受(表*)而不是(List))。

希望這有助於XD


編輯:

嘗試撥打電話到的addNumbers之前分配 '和'()。

lst1 = arrToList(pa, 1); 
lst2 = arrToList(pb, 1); 
sum = createEmptyList(); 

我還是認爲你的數據結構是一個有點古怪的方式:S

0

您遇到了createEmptyList的問題。你在那裏聲明一個名爲res的列表並返回結構,但是這個函數返回的那一刻結構就不再有效了。 嘗試使用malloc(對於結構體),然後將指針返回給調用者。您在* sum開頭使用此函數。

這是一個和chmike發現的類似的bug,所以你最好修復兩者。