2015-06-08 21 views
-1

我想重寫我的一些代碼來使用線程,因爲我試圖在C++中學習它。我有這種方法:在C++中乘以多項式與線程

template <typename T> 
Polynomial<T> Polynomial<T>::operator *(const Polynomial<T>& other) { 
    std::vector<std::future<std::vector<T>>> tempResults; 

    for (auto i = 0; i < Coefficients.size(); i++) { 
     tempResults.push_back(std::async(std::launch::async, [&other, this](int i) { 
      std::vector<T> result(i + other.GetCoefficientsSize() + 2); 
      std::fill(result.begin(), result.end(), 0); 

      for (auto j = 0; j < other.GetCoefficientsSize(); j++) { 
       result.at(j + i + 1) = other.GetCoefficient(j) * Coefficients.at(i); 
      } 
     return result; 
    }, Coefficients.at(i))); 
} 

std::mutex multiplyMutex; 
std::vector<T> total(Coefficients.size() + other.Coefficients.size()); 

for (auto i = 0; i < tempResults.size(); i++) { 
    std::vector<T> result = tempResults.at(i).get(); 
    std::lock_guard<std::mutex> lock(multiplyMutex); 
    for (T value : result) { 
     total.at(i) += value; 
    } 
} 
Polynomial<T> result(total); 
return result; 

經過多次試驗和錯誤,我得到的代碼進行編譯。 。但是運行時,我在這條線走出越界異常的指標:

std::vector<T> result = tempResults.at(i).get(); 

此外,一步一步調試讓我發現,在文件的「未來」的某種異常處理是在這條線運行以及:

result.at(j + i + 1) = other.GetCoefficient(j) * Coefficients.at(i); 

你能確定發生了什麼嗎?

+0

該錯誤表示第58行有一個不帶1個參數的函數。它可能需要更多或更少。 – cehnehdeh

+2

尋求調試幫助的問題(「爲什麼這個代碼不工作?」)必須包含所需的行爲,特定的問題或錯誤以及在問題本身中重現問題所需的最短代碼。沒有明確問題陳述的問題對其他讀者無益。請參閱:[如何創建最小,完整和可驗證的示例](http://stackoverflow.com/help/mcve) –

+0

對不起,該算法的期望行爲是標題和第一個算法的結果i張貼,這是有效的。因此,我的問題陳述是「爲了使底層算法等同於我所做的第一個算法,我需要改變哪裏或哪些內容?」。關於「58行」,它指的是一些文件「xrefwrap」,它不是我自己代碼的一部分,爲什麼我不知道如何調試它。 – Treeline

回答

1

我終於自己解決了這個問題。事實證明,我犯了一個愚蠢的錯誤,將異步任務的結果存儲在索引Coefficients.at(i)上,這顯然是多項式的係數。這反過來使得異步任務的結果在tempResults向量上出界。我真正需要的是存儲在i

一旦我有它的工作,我也發現最後for循環有問題。完整的工作結果可以在下面看到。

template <typename T> 
Polynomial<T> Polynomial<T>::operator *(const Polynomial<T>& other) { 
    std::vector<std::future<std::vector<T>>> tempResults; //Results from async will be stored here 

    for (int i = 0; i < Coefficients.size(); i++) { 
     tempResults.push_back(std::async(std::launch::async, [&other, this](int i) { //Start threads for each Coefficient 
      std::vector<T> result(Coefficients.size() + other.GetCoefficientsSize()); //Size of result is the combined degree 
      std::fill(result.begin(), result.end(), 0); 

      for (auto j = 0; j < other.GetCoefficientsSize(); j++) { 
       result.at(i + j + 1) += Coefficients.at(i) * other.GetCoefficient(j); 
      } 
      return result; 
     }, i)); //save in tempResults at i 
    } 
    std::mutex multiplyMutex; 
    std::vector<T> total(Coefficients.size() + other.Coefficients.size()); 

    for (auto i = 0; i < tempResults.size(); i++) { //Combine tempResults in total 
     std::vector<T> result = tempResults.at(i).get(); //Get result of async task 
     std::lock_guard<std::mutex> lock(multiplyMutex); //Disallow concurrent access to the final variable 
     for (auto j = 0; j < result.size(); j++) { 
      total.at(j) += result.at(j); 
     } 
    } 
    Polynomial<T> result(total); 
    return result; 
}