2013-03-04 14 views
0

我正在使用CLHEP庫,並遇到一些困難。在這些改變之前,我一直在生成一組粒子動量作爲CLHEP對象的矢量(std :: vector),然後將這些轉換爲普通數組的矢量 - 仍然包含相同的動畫 - 用於另一個程序(MadGraph)使用。 我希望把這個轉換程序到一個新的功能,所以我做了這個:當我將一組命令移動到一個單獨的函數時,代碼段錯誤

std::vector<double*> MadGraphConvert(vector<CLHEP::HepLorentzVector> p) { 

double ptemp[6][4]; 

for (int i = 0; i < 6; i++) { 
    ptemp[i][0] = p.at(i).e(); 
    ptemp[i][1] = p.at(i).x(); 
    ptemp[i][2] = p.at(i).y(); 
    ptemp[i][3] = p.at(i).z(); 
} 

// Give particles to MG in a 'vector of arrays' format 
std::vector<double*> p_MG; 

p_MG.push_back(ptemp[0]); 
p_MG.push_back(ptemp[1]); 
p_MG.push_back(ptemp[2]); 
p_MG.push_back(ptemp[3]); 
p_MG.push_back(ptemp[4]); 
p_MG.push_back(ptemp[5]); 

return p_MG; 
} 

現在,當我跑我的代碼的東西在這個其他代碼拋出一個段錯誤,但我想我路過我面前?我的舊轉換集看起來像這樣:

p[0][0] = pa.e(); 
    p[0][1] = pa.x(); 
    p[0][2] = pa.y(); 
    p[0][3] = pa.z(); 

    p[1][0] = pb.e(); 
    p[1][1] = pb.x(); 
    p[1][2] = pb.y(); 
    p[1][3] = pb.z(); 
. 
' 
' 
    std::vector<double*> p_MG; 

    p_MG.push_back(p[0]); 
    p_MG.push_back(p[1]); 
    p_MG.push_back(p[2]); 
    p_MG.push_back(p[3]); 
    p_MG.push_back(p[4]); 
    p_MG.push_back(p[5]); 

如果有人能夠發現這兩種方法的區別在哪裏,我將非常感激! 乾杯 傑克

回答

4

vector包含懸空指針,因爲它是從一個局部變量,數組ptemp,其超出範圍的功能MadGraphConvert()返回時與地址填充。解引用懸空指針是未定義的行爲,在這種情況下,它會導致分段錯誤。

使用std::vector<std::vector<double>>代替:

std::vector<std::vector<double>> ptemp(6, std::vector<double>(4)); 

for循環將工作是(因爲這構造函數創建vector與六大要素與每一個元素是另一個四double小號vector),就回到ptemp(記住改變返回值MadGraphConvert())。


如果作爲評價此答案,類型變化被禁止然後動態地分配使用newdouble[4]陣列。該vector現在擁有的陣列,必須delete[]當他們不再需要:

// In function. 
std::vector<double*> ptemp(6); // By default, created with six null pointers. 
try 
{ 
    for (size_t i(0), count(ptemp.size()); i < count; i++) 
    { 
     ptemp[i] = new double[4]; 
     // Remainder of loop as before. 
    } 
} 
catch (std::exception const&) // std::out_of_range, std::bad_alloc 
{ 
    // Exception safety. 
    // delete[] whatever was allocated, remember that 
    // delete[] on a null pointer is a no-op so no 
    // prior check required. 
    for (auto i : ptemp) delete[] i; 
    throw; 
} 

,就回到ptemp。後來,當vector不再需要:

// c++11 
for (auto i : ptemp) delete[] i; 

// c++03 
for (std::vector<double*>::iterator i(ptemp.begin()); 
    i != ptemp.end(); 
    i++) 
{ 
    delete[] (*i); 
} 
+0

您好感謝幫助, 這是我原來的做法,但Madgraph希望動量的陣列,其聲明如下的載體傳遞: 無效setMomenta(矢量< double * >& momenta){p = momenta;} 有沒有辦法在保持這種格式的同時閃避懸掛指針? – JMzance 2013-03-04 12:45:08

+0

@JackMedley,是的。我會更新答案。 – hmjd 2013-03-04 12:50:27

+0

好吧,在我的循環它仍然編譯好,但segfault在同一位置仍然存在。我可能會嘗試在main中創建ptemp數組,然後將它傳遞給函數,填充它並從main訪問它,這應該是正確的?乾杯 – JMzance 2013-03-04 13:22:20

相關問題