2016-05-22 37 views
-5

我正在學習C++,並決定製作一些小而短的函數來練習。這下面的代碼位會給我一個不正確的答案:爲什麼這一個,毫無意義的代碼是唯一讓這個功能起作用的東西?

float pairwiseSum(float data[], int arraySize, int naive_sum_size=8) { 
    if (arraySize <= naive_sum_size) { 
    return naiveSum(data, arraySize); 
    } else { 
    int m = arraySize/2; 
    return pairwiseSum(&data[0], m) + pairwiseSum(&data[m], arraySize-m); 
    } 
} 

naiveSum在這種情況下只是遍歷數組積累的總和,似乎很好地工作。如果我有1秒64的陣列,它會告訴我的總和是288

然而,這個版本的代碼工作完美每次:

float pairwiseSum(float data[], int arraySize, int naive_sum_size=8) { 
    if (arraySize <= naive_sum_size) { 
    cout << ""; 
    return naiveSum(data, arraySize); 
    } else { 
    int m = arraySize/2; 
    return pairwiseSum(&data[0], m) + pairwiseSum(&data[m], arraySize-m); 
    } 
} 

我使用的Fedora 21,並與編譯g ++ 4.9.2

爲什麼一個函數有效,但另一個失敗?

編輯:它出現在我的main.cpp文件中的完整程序如下。

#include <iostream> 
#include <stdlib.h> 

using namespace std; 


float naiveSum(float data[], int arraySize) { 
    float sum; 
    for (int i = 0; i < arraySize; i++) 
    sum += data[i]; 
    return sum; 
} 


// Divide-and-conquer algorithm is a little faster than the 
// Kahan Summation Algorithm, but also less accurate. 
float pairwiseSum(float data[], int arraySize, int naive_sum_size=8) { 
    if (arraySize <= naive_sum_size) { 
    //cout << ""; 
    return naiveSum(data, arraySize); 
    } else { 
    int m = arraySize/2; 
    return pairwiseSum(&data[0], m) + pairwiseSum(&data[m], arraySize-m); 
    } 
} 


int main() { 
    const int SIZE = 64; 
    const int rndRange = 100; 

    // generate random array 
    srand(time(NULL)); 
    float xs[SIZE]; 
    for (int i=0; i<SIZE; i++) 
    // +1 prevents division by zero 
    //xs[i] = rand() % rndRange/(float)(rand() % rndRange + 1); 
    xs[i] = 1; 

    // Print kahan sum of random array 
    //cout << "Kahan Sum: " << kahanSum(xs, SIZE) << endl << endl; 
    cout << endl << pairwiseSum(xs, SIZE) << endl; 

    return 1; 
} 

編輯:是的,這確實是一個問題,總和沒有被初始化。謝謝你的幫助。

+6

_undefined behaviour_立即出現紅色標記。啓動你的調試器並檢查你的數組索引。 –

+3

因爲你需要提供[mcve]。 –

+0

你在問爲什麼你沒有顯示的功能不起作用。 –

回答

6

sum未在naiveSum中初始化。剩下的只是未定義的行爲(由sum中的不確定值引起)不同或不具有不相關的cout << ""行。

有許多不同的方法cout << ""可能導致sum的不確定初始值最終爲零,從而創建naiveSum正常工作的外觀。

+0

感謝您對cout <<「」如何產生影響的解釋。對我來說這似乎很奇怪,並在想知道它是否按照我不明白的順序執行。 – Ram

+1

@ user3471004:你必須看起來像彙編代碼來確定。例如,優化器可能會將'sum'與一些CPU(FPU)寄存器相關聯。如果沒有'cout'這行寄存器包含一些舊的非零值(從以前的計算),你的'naiveSum'似乎工作不正確。使用'cout'行這個寄存器被'cout'用於某種目的,並且最終被清零,這導致你的'naiveSum'看起來工作正常。這只是一個可能的解釋。 – AnT

+1

基本上,在現實生活中,無論你的'sum'存儲在哪裏(寄存器,內存等),它都將以其前一個「用戶」存儲在該區域的一些「垃圾」值開始其生命。通過添加'cout <<「」'行,您可以有效地更改以前的用戶,從而更改它留下的垃圾。恰恰恰恰相反,'cout <<「」'離開「更好」垃圾(一個零值)在那個區域中,'sum'將在以後佔據。儘管這是一個純粹的事故。 – AnT