c++ - 当我将一组命令移到一个单独的函数中时出现代码段错误

标签 c++ segmentation-fault

我在使用 CLHEP 库时遇到了一些困难。在进行这些更改之前,我一直在生成一组粒子动量作为 CLHEP 对象的 vector (std::vector),然后将它们转换为法线数组的 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]);

如果有人能找出这两种方法的不同之处,我将不胜感激! 干杯 jack

最佳答案

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

使用 std::vector<std::vector<double>>相反:

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

for loop 将按原样工作(因为此构造函数创建了具有六个元素的 vector,每个元素都是另一个 vector 四个 double s )并且只返回 ptemp (记得更改 MadGraphConvert() 的返回值)。


如果,正如对此答案的评论,禁止类型更改,则动态分配 double[4]使用 new 的数组. 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);
}

关于c++ - 当我将一组命令移到一个单独的函数中时出现代码段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15201783/

相关文章:

c++ - 在循环中从 unordered_map 中删除元素

c++ - 当 model_completion 设置为 false 时 Z3 会返回什么?

php - 为什么我在此 PHP 命令行脚本中出现此段错误?

c++ - 指针数组的段错误

python - 使用 ctypes 和 SSE/AVX 有时会出现段错误

assembly - 使用 OUT 指令在传统 PC 扬声器上生成声音

c++ - 如何比较谷歌模拟中的特殊领域?

c++ - 如何将 QListWidget/QStandardItemModel 项目映射到我的逻辑?

c++ - 使用 OpenGL 的 2D Sprite 动画技术

c - 使用 char,转换为 int 作为数组索引以将 "chars"的频率存储在文本文件中