2015-06-20 109 views
0

時我需要一些幫助,我找不到任何相關的搜索。代碼不起作用。但是在調試

所以我正在寫一個C程序和一些奇怪的事情。我的程序崩潰時,我正常運行但當我調試它,它工作正常。我不知道發生了什麼事。

這是一個任務,它是在星期三,所以我嚇壞了一點。

(我使用的代碼塊IDE,如果這是任何幫助。)

編輯: 很抱歉沒有從一開始就張貼此,我想這個問題可能已經使用調試器錯誤或不得不改變了我調試器設置(如果甚至可能的話)。 下面是接縫會導致問題的功能:

double **makeMatrix(struct graph *head, char **nodes) 
{ 
    double **tmpMatrix=NULL; 
    int i=0, j=0; 
    struct graph *tmp=NULL; 


    if(nodes==NULL || head==NULL) 
     return NULL; 

    for(i=0; nodes[i] != NULL; i++); 

    tmpMatrix=calloc(i+1, sizeof(double*)); 

    if(NULL==tmpMatrix) 
    { 
     printf("No Memory!"); 
     return NULL; 
    } 

    for(j=0; j<i; j++) 
    { 
     tmpMatrix[j]=calloc(i+1, sizeof(double*)); 

     if(NULL==tmpMatrix[j]) 
     { 
      printf("No Memory!"); 
      return NULL; 
     } 
     tmpMatrix[j][i] = -INF; 
    } 

    for(i=0; tmpMatrix[i] != NULL; i++) 
    { 
     for(j=0; tmpMatrix[i][j] != -INF; j++) 
     { 
      tmpMatrix[i][j] = INF; 
     } 
    } 

    for(tmp=head; tmp->fromNode >=0; tmp= tmp->next) 
    { 
     tmpMatrix[tmp->fromNode][tmp->toNode] = tmp->length; 
     printf("%f\n", tmpMatrix[tmp->fromNode][tmp->toNode]); 
    } 

    return tmpMatrix; 
} 

的任務是寫一個程序,它能夠讀取節點和圖形計算shortes路徑。哪裏有Dijkstra算法來解決這個問題。這就是爲什麼我們必須創建一個矩陣來存儲邊的長度。

此外,使用調試器,我一步一步地執行它。

+0

請向我們顯示您的代碼。 – Rndp13

+3

對於任何人來說,沒有太多的信息可以幫助你。見[問]。 –

+1

Wellcome to StackOverflow。爲了我們可以幫助您,請考慮發佈一些代碼,崩潰點,消息輸出,日誌文件,... – Trimax

回答

1

我看到這取決於所有的代碼,並輸入了一些問題或潛在問題還沒有顯示:

  1. 行:

    tmpMatrix[j]=calloc(i+1, sizeof(double*)); 
    

    應該是:

    tmpMatrix[j]=calloc(i+1, sizeof(double)); 
    

    如果sizeof(double*) == 8你可能是偶然的,但更好的是實際上是正確的

  2. 在第一個for循環中,您似乎正在計算nodes數組的大小。在這種情況下,我不明白節點的用法,因爲它不在函數的其他地方使用。更好的函數簽名是傳遞所需數組的大小。確保nodes正確NULL終止或您會遇到問題。我還要再添變數,使數組大小明確,因爲你以後重用i,是這樣的:

    int arraySize = 0; 
    ... 
    for (i = 0; nodes[i] != NULL; ++i); 
    arraySize = i; 
    tmpMatrix = calloc(arraySize + 1, sizeof(double*)); 
    
  3. 對於tmpMatrix值設置爲INF它會更好地使用顯式數組索引,如:

    for (i = 0; i < arraySize; ++i) 
    { 
        for (j = 0; j < arraySize; ++j) 
        { 
         tmpMatrix[i][j] = INF; 
        } 
    } 
    

    這使得它更清晰你在做什麼,而且更少出錯。

  4. 你應該明確地爲您在您的最後一個循環一個NULL指針:

    for (tmp = head; tmp->fromNode >= 0; tmp = tmp->next) 
    

    如果鏈接列表不設置正確,然後tmp可能成爲NULL,你會取消對它的引用導致未定義的行爲。一個簡單的檢查添加到像循環:

    for (tmp = head; tmp != NULL && tmp->fromNode >= 0; tmp = tmp->next) 
    
  5. 您應該檢查有效的數組索引tmpMatrix你最後的循環中:

    tmpMatrix[tmp->fromNode][tmp->toNode] = tmp->length; 
    

    如果tmp->fromNodetmp->toNode你會溢出無效數組索引/下溢數組並導致UB。即使你「知道」這些價值觀應該是正確的它是更安全,只是在情況下添加一個檢查:

    if (tmp->fromNode >= 0 && tmp->fromNode < arraySize && 
        tmp->toNode >= 0 && tmp->toNode < arraySize) 
    { 
        ... 
    } 
    

很多這些點都在「防禦式編程」的範疇。是的,nodeshead應該是NULL終止的並且具有正確的索引,但是也許在某處存在另一個錯誤,並且它們不是,或者接收到無效輸入,或者雜散宇宙射線在存儲單元中翻轉了一點。通過仔細檢查一下你的輸入,你可以防止UB發生,並像你經歷過的那樣隨機撞上你。

+0

我現在覺得很愚蠢。我檢查了十幾次代碼,每次忽略不應該存在的星號。這是程序崩潰的全部原因。仍然奇怪,它在調試時工作... 無論如何,謝謝! – Gin

+0

是的,不幸的是,一個未定義行爲的結果是沒有什麼......它似乎工作正常。然後你改變一個看起來不相關的東西,它就會崩潰在你身上。 – uesp