【问题标题】:boost multiarray segmentation fault提升多阵列分割错误
【发布时间】:2016-10-05 12:48:19
【问题描述】:

我正在编写一个代码,我使用 3 维 boost 多数组来保存坐标。但我总是在某些时候遇到分段错误。 boost 多数组大小如何受到限制,我该如何绕过这些限制?

这是重现问题的简化测试代码:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <string>
#include <algorithm>
#include <map>

#include <boost/multi_array.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>
#include "Line.h"

#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>

typedef struct {
    Eigen::Vector3d coords;
    int gpHostZone;
    int gpHostFace;
    int calculated;
} Vertex;


class LGR {
public:
    LGR (int i, int j, int k) :
        grid(boost::extents[i][j][k])
    {
    };

    std::string name;
    std::vector<int> hostZones;
    std::vector<int> refine;
    boost::multi_array<Vertex*, 3> grid;
    std::vector<double> data;
 };

 int main(void){
   LGR lgr(11,11,21);
   std::cout << lgr.grid.size();
   std::vector<LGR> v;
   std::vector<Vertex> vertexDB;
   for(int i = 0; i < 1; i++ ){

     for(int j = 0; j < lgr.grid.size(); j++ ){
       for(int k = 0; k < lgr.grid[0].size(); k++ ){
         for(int l = 0; l < lgr.grid[0][0].size(); l++ ){
           Vertex coord;
           coord.coords << i,j,k;
           coord.gpHostZone = 0;
           coord.gpHostFace = 0;
           coord.calculated = 0;
           vertexDB.push_back(coord);
           lgr.grid[j][k][l] = &(vertexDB.back());
         }
       }
     }

     for(int j = 0; j < lgr.grid.size(); j++ ){
       for(int k = 0; k < lgr.grid[0].size(); k++ ){
         for(int l = 0; l < lgr.grid[0][0].size(); l++ ){
           std::cout << "At ("<< i << ","<< j << ","<< k << "," << l << ")\n";
           std::cout << lgr.grid[j][k][l]->coords<<"\n\n";
         }
       }
     }
   }
   return 1;
 }

请不要对包含的内容发表评论。我只是从实际代码中复制并粘贴。大多数可能在这里不需要。这些尺寸来自一个真实的例子,所以我实际上需要这些尺寸(可能更多)。

【问题讨论】:

  • lgr.grid[j][k][l] = &amp;(vertexDB.back()); -- 在向量中存储指向项目的指针不是一个好主意。如果向量变为调整大小的迭代器并且指向项目的指针变得无效。

标签: c++ boost segmentation-fault


【解决方案1】:

以下是导致未定义行为的明确问题,与boost::multiarray 无关。

这些行:

std::vector<Vertex> vertexDB;
//...
vertexDB.push_back(coord);
lgr.grid[j][k][l] = &(vertexDB.back());

调整vertexDB 向量的大小,然后将指向向量中最后一项的指针存储到lgr.grid[j][k][l]。这样做的问题是,由于在调整向量大小时向量必须重新分配内存,指向向量中项目的指针和迭代器可能会失效。

这会在后面的循环中体现出来:

std::cout << lgr.grid[j][k][l]->coords<<"\n\n";

不保证您之前分配的地址是有效的。

对此的快速解决方法是使用std::list&lt;Vertex&gt;,因为将项目添加到std::list 不会使迭代器/指针无效。

【讨论】:

  • 好吧,现在我觉得有点傻。解释清楚之后,问题就很明显了。并且使用 List 对于测试代码来说效果很好(不幸的是我无法测试真正的代码,因为不知何故我需要的一个类被完全破坏了,现在我必须重新创建它......)。不管怎样,它有效。谢谢 PaulMcKenzie...
猜你喜欢
  • 1970-01-01
  • 2012-03-08
  • 2016-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-10
相关资源
最近更新 更多