简体   繁体   English

提升多阵列分段错误

[英]boost multiarray segmentation fault

I`m writing a code for which I'm using a 3 dimensional boost multiarray to save coordinates.我正在编写一个代码,我使用 3 维 boost 多数组来保存坐标。 But I always get a segmentation fault at some point.但我总是在某个时候遇到分段错误。 How are boost multiarray sizes limited and how can I get around those limits? boost 多阵列大小如何受到限制,我该如何绕过这些限制?

Here is a simplified test code that reproduces the problem:这是重现问题的简化测试代码:

#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;
 }

Please do not comment on the includes.请不要对包含的内容发表评论。 I just copy and pasted from the actual code.我只是从实际代码中复制和粘贴。 Most of the are probably not needed here.大多数在这里可能不需要。 The dimensions are from a real example, so I actually need those kind of dimensions (and probably more).尺寸来自一个真实的例子,所以我实际上需要那些尺寸(可能更多)。

The following is a definite issue that leads to undefined behavior, and doesn't have anything to do with boost::multiarray .以下是导致未定义行为的明确问题,与boost::multiarray

These lines:这些线路:

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

resizes the vertexDB vector and then stores a pointer to the last item in the vector to lgr.grid[j][k][l] .调整vertexDB向量的大小,然后将指向向量中最后一项的指针存储到lgr.grid[j][k][l] The problem with this is that pointers and iterators to items in a vector may become invalidated due to the vector having to reallocate memory when resizing the vector.这样做的问题是,由于在调整向量大小时向量必须重新分配内存,指向向量中项的指针和迭代器可能会失效。

This manifests itself later here, in the subsequent loop:这在后面的循环中表现出来:

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

There is no guarantee that the address you assigned previously is valid.无法保证您之前分配的地址有效。

A quick fix for this is to use a std::list<Vertex> , since adding items to a std::list does not invalidate iterators / pointers.对此的快速解决方法是使用std::list<Vertex> ,因为将项目添加到std::list不会使迭代器/指针无效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM