C++ 将一组命令移动到单独的函数中时的代码分段错误

C++ 将一组命令移动到单独的函数中时的代码分段错误,c++,segmentation-fault,C++,Segmentation Fault,我在CLHEP图书馆工作,遇到了一些困难。在这些改变之前,我一直在生成一组粒子动量作为CLHEP对象的向量(std::vector),然后将它们转换为普通数组的向量——仍然包含相同的动量——供另一个程序(MadGraph)使用。 我想把这个转换例程放到一个新函数中,所以我做了这个: std::vector<double*> MadGraphConvert(vector<CLHEP::HepLorentzVector> p) { double ptemp[6][4];

我在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;
}
std::向量MadGraphConvert(向量p){
双ptemp[6][4];
对于(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();
}
//以“数组向量”格式将粒子赋予MG
std::载体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]);
返回p_MG;
}
现在,当我运行我的代码时,另一个代码中的某个东西抛出了一个segfault,但我认为我正在传递我之前所拥有的?我的旧转换集如下所示:

    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]);
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::载体p_-MG;
p_MG.推回(p[0]);
p_MG.推回(p[1]);
p_MG.推回(p[2]);
p_MG.推回(p[3]);
p_MG.推回(p[4]);
p_MG.推回(p[5]);
如果有人能指出这两种方法的不同之处,我将不胜感激! 干杯
杰克向量
包含悬空指针,因为它填充了来自局部变量的地址,数组
ptemp
,当函数
MadGraphConvert()
返回时,该数组超出范围。取消对悬挂指针的引用是未定义的行为,在这种情况下会导致分段错误

改用
std::vector

std::vector<std::vector<double>> ptemp(6, std::vector<double>(4));
然后返回
ptemp
。稍后,当不再需要
矢量时:

// 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;
}
// c++11
for (auto i : ptemp) delete[] i;

// c++03
for (std::vector<double*>::iterator i(ptemp.begin());
     i != ptemp.end();
     i++)
{
    delete[] (*i);
}
/c++11
对于(自动i:ptemp)删除[]i;
//c++03
for(std::vector::iterator i(ptemp.begin());
i!=ptemp.end();
(i++)
{
删除[](*i);
}

向量
包含悬空指针,因为它填充了来自局部变量(数组
ptemp
)的地址,当函数
MadGraphConvert()返回时,该数组超出范围。取消对悬挂指针的引用是未定义的行为,在这种情况下会导致分段错误

改用
std::vector

std::vector<std::vector<double>> ptemp(6, std::vector<double>(4));
然后返回
ptemp
。稍后,当不再需要
矢量时:

// 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;
}
// c++11
for (auto i : ptemp) delete[] i;

// c++03
for (std::vector<double*>::iterator i(ptemp.begin());
     i != ptemp.end();
     i++)
{
    delete[] (*i);
}
/c++11
对于(自动i:ptemp)删除[]i;
//c++03
for(std::vector::iterator i(ptemp.begin());
i!=ptemp.end();
(i++)
{
删除[](*i);
}

Hi感谢您的帮助,这是我最初的方法,但Madgraph希望动量作为数组向量传递,其声明如下:void setMomenta(vector&momenta){p=momenta;}有没有办法在保持这种格式的同时避开挂起的指针?好的,在我的循环中,它仍然编译Ok,但是相同位置的segfault仍然存在。我可能会尝试在main中创建ptemp数组,将其传递给函数,填充它,然后从main访问它,这样应该可以正常工作吗?Cheers@JackMedley,我不确定这为什么不起作用(我只是仔细检查了一下)。如果有,建议使用
valgrind
。您的建议会起作用,但由于
向量
数组
之间存在生命周期安排,因此很危险。您好,感谢您的帮助,这是我最初的方法,但Madgraph希望动量作为数组向量传递,其声明如下:void setMomenta(vector&momenta){p=momenta;}有没有办法在保持这种格式的同时避开挂起的指针?好的,在我的循环中,它仍然编译Ok,但是相同位置的segfault仍然存在。我可能会尝试在main中创建ptemp数组,将其传递给函数,填充它,然后从main访问它,这样应该可以正常工作吗?Cheers@JackMedley,我不确定这为什么不起作用(我只是仔细检查了一下)。如果有,建议使用
valgrind
。您的建议将起作用,但由于
向量
数组
之间存在生命周期安排,因此是危险的。