簡體   English   中英

將結構插入地圖時出現分段錯誤

[英]Segmentation fault when inserting struct into a map

被填充的mapBase參數將代表一個坐標系。 我使用std::map輕松地根據 x 對坐標進行排序,然后與由內部映射排序的 y 坐標配對。 內部映射的值稍后會保存額外的信息。 現在它填充了虛擬數據。

我正在嘗試將結構插入std::map ,但在插入時出現段錯誤。 段錯誤並不總是一致的。 有時插入會工作多次,然后在沒有特定的次數后出現段錯誤。

我嘗試添加調試語句,通過使用std::map::insert函數的結果並查看結果的第二個字段來告訴我何時成功插入某些內容。 這僅在沒有發生段錯誤時才有用,並且通常總是如此,因為我在被調用函數開始時清除了mapBase 我還嘗試使用智能共享指針作為baseMap的最終值類型,而不僅僅是結構對象本身。 這並沒有改變我的結果。 我也嘗試分配*(new cell())具有相同的結果。 我提供了下面的基本代碼。

主要的:

    #include <map>
    #include <cmath>
    #define DEG_TO_RAD(deg) deg * M_PI / 180

    int main(int argc, char **argv)
    {
      // vector of lidar range, angle pairs
      std::vector<std::pair<double, double>> lidarData {{0.585, -179.41},
                                                        {0.689, -151.672},
                                                        {0.671, 56.6557},
                                                        {0.717, 122.164},
                                                        {0.611, 159.344},
                                                        {0.586, 175.279}};
    
      // convert returns to x, y coordinate point
      std::vector<Eigen::Matrix<double, 2, 1>> points;
      for(const auto& beam : lidarData)
      {
        double angle = DEG_TO_RAD(beam.second);
        double range = beam.first;
        double x = range * cos(angle); // r * cos(theta)
        double y = range * sin(angle); // r * sin(theta)
        Eigen::Matrix<double, 2, 1> point;
        point << x, y;
        points.emplace_back(point);
      }
    
      auto* newA = new A();
      newA->doSomething(points);
      
      return 0;
    }

標題:

class A {
    public:
        A();

        ~A();
  
        void doSomething(std::vector<Eigen::Matrix<double, 2, 1>> &points);
  
    private:
        struct cell {
            Eigen::Matrix<double, 2, 1> mean;
            Eigen::Matrix<double, 2, 2> covariance;
            std::vector<double> x_m {};
            std::vector<double> y_m {};
            std::vector<Eigen::Matrix<double, 2, 1>> hits {};

            cell();
        };

        // define a map keyed by a x coordinate with a value of  std::map.
        // inner map is keyed by a y coordinate with a value of struct type cell.
        typedef std::map<double, std::map<double, cell>> map;
        map mapBase;
    }
}

來源

A::A() {}

A::~A() {}

void A::doSomething(std::vector<Eigen::Matrix<double, 2, 1>> &points) {
    mapBase.clear();
    for (const auto &point : points) {
        auto x = point.x();
        auto y = point.y();

        auto xIt = mapBase.find(x);
        if (xIt == mapBase.end()) { // coordinate does not exist if true
            std::map<double , cell> yPair;
            yPair.insert(std::make_pair(y, cell()));  // Segfault happens here
            mapBase.insert(std::make_pair(x, yPair));
        } else { // x exist in map, but check if y does
            auto yIt = mapBase.at(x).find(y);
            if (yIt == mapBase.at(x).end()) { // y does not exist at x if true
                mapBase.at(x).insert(std::make_pair(y, cell()));
            }
        }

        // Emplace values at the new cell in the map. 
        mapBase.at(x).at(y).x_m.emplace_back(x);
        mapBase.at(x).at(y).y_m.emplace_back(y);
        mapBase.at(x).at(y).hits.emplace_back(Eigen::Matrix<double, 2, 1>());
        mapBase.at(x).at(y).mean.setOnes();
        mapBase.at(x).at(y).covariance.setOnes();
    }
};

A::cell::cell() {
    mean.setZero();
    covariance.setOnes();
    x_m.clear();
    y_m.clear();
    hits.clear();
}

在定期執行代碼時,我只是在插入結構時遇到分段錯誤(核心轉儲)。 使用gdb,回溯如下:

#0  std::pair<double const, cell>::pair<double, A::cell, true> (__p=..., this=<optimized out>) at /usr/include/c++/7/bits/stl_pair.h:362
#1  __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<double const, A::cell> > >::construct<std::pair<double const, A::cell>, std::pair<double, A::cell> > (this=<optimized out>, __p=<optimized out>) at /usr/include/c++/7/ext/new_allocator.h:136
#2  std::allocator_traits<std::allocator<std::_Rb_tree_node<std::pair<double const, A::cell> > > >::construct<std::pair<double const, A::cell>, std::pair<double, A::cell> > (__a=..., __p=<optimized out>) at /usr/include/c++/7/bits/alloc_traits.h:475
#3  std::_Rb_tree<double, std::pair<double const, A::cell>, std::_Select1st<std::pair<double const, A::cell> >, std::less<double>, std::allocator<std::pair<double const, A::cell> > >::_M_construct_node<std::pair<double, A::cell> > (this=0x7fffffffd6d0, __node=0x55555585ed90) at /usr/include/c++/7/bits/stl_tree.h:626
#4  std::_Rb_tree<double, std::pair<double const, A::cell>, std::_Select1st<std::pair<double const, A::cell> >, std::less<double>, std::allocator<std::pair<double const, A::cell> > > >::_M_create_node<std::pair<double, A::cell> > (this=0x7fffffffd6d0) at /usr/include/c++/7/bits/stl_tree.h:643
#5  std::_Rb_tree<double, std::pair<double const, A::cell>, std::_Select1st<std::pair<double const, A::cell> > > std::less<double>, std::allocator<std::pair<double const, A::cell> > >::_M_emplace_unique<std::pair<double, A::cell> > (this=this@entry=0x7fffffffd6d0) at /usr/include/c++/7/bits/stl_tree.h:2351
#6  0x0000555555596ddd in std::map<double, A::cell, std::less<double>, std::allocator<std::pair<double const, A::cell> > >::emplace<std::pair<double, A::cell> > (this=0x7fffffffd6d0) at /usr/include/c++/7/bits/stl_map.h:569
#7  A::doSomething (this=this@entry=0x5555558082d0, points=std::vector with 49 elements = {...}) at ...

回溯並沒有使問題變得明顯,但進一步的調試表明,從結構中刪除均值和協方差可以使應用程序運行而不會出錯。 我可以將它們分成單獨的參數,但在我看來這並不是正確的解決方案。 也許在進行配對時的復制調用會導致問題和特征參數的處理管理不善? 對我的問題的理解和解決方案的任何幫助將不勝感激。

我認為您必須首先定義對的類型: std::pair<double,cell> new_pair = makepair(y,cell)然后將其插入到地圖中。

您在上面給出的代碼片段中有一些錯誤,我已將其刪除。 該程序現在可以正常工作而不會出現分段錯誤。 你可以試試這個並確認我的相同。

mainneweighen.cpp

#include <vector>
#include <Eigen/Dense>
#include "neweigen.h"
int main(int argc, char **argv)
    {
      std::vector<std::pair<double, double>> lidarData {{0.585, -179.41},
                                                        {0.689, -151.672},
                                                        {0.671, 56.6557},
                                                        {0.717, 122.164},
                                                        {0.611, 159.344},
                                                        {0.586, 175.279}};
    
    
      std::vector<Eigen::Matrix<double, 2, 1>> points;
      for(const auto& beam : lidarData)
      {
        double x = beam.first * cos(beam.second); // r * cos(theta)
        double y = beam.first * sin(beam.second); // r * sin(theta)
        Eigen::Matrix<double, 2, 1> point;
        point << x, y;
        points.emplace_back(point);
      }
    
      auto* newA = new A();
      newA->doSomething(points);
      
      return 0;
    }

新特征文件

#include "neweigen.h"

A::A() {}

A::~A() {}

void A::doSomething(std::vector<Eigen::Matrix<double, 2, 1>> &points) {
    mapBase.clear();
    for (const auto &point : points) {
        auto x = point.x();
        auto y = point.y();

        auto xIt = mapBase.find(x);
        if (xIt == mapBase.end()) { // coordinate does not exist if true
            std::map<double , cell> yPair;
            yPair.insert(std::make_pair(y, cell()));  // Segfault happens here
            mapBase.insert(std::make_pair(x, yPair));
        } else { // x exist in map, but check if y does
            auto yIt = mapBase.at(x).find(y);
            if (yIt == mapBase.at(x).end()) { // y does not exist at x if true
                mapBase.at(x).insert(std::make_pair(y, cell()));
            }
        }

        // Emplace values at the new cell in the map. 
        mapBase.at(x).at(y).x_m.emplace_back(x);
        mapBase.at(x).at(y).y_m.emplace_back(y);
        mapBase.at(x).at(y).hits.emplace_back(Eigen::Matrix<double, 2, 1>());
    }
}

A::cell::cell() {
    mean.setZero();
    covariance.setOnes();
    x_m.clear();
    y_m.clear();
    hits.clear();
}


新特征

#ifndef FILE_H
#define FILE_H
#include <vector>
#include <Eigen/Dense>
#include <map>
class A {
    public:
        A();

        ~A();
  
        void doSomething(std::vector<Eigen::Matrix<double, 2, 1>> &points);
  
    private:
        struct cell {
            Eigen::Matrix<double, 2, 1> mean;
            Eigen::Matrix<double, 2, 2> covariance;
            std::vector<double> x_m {};
            std::vector<double> y_m {};
            std::vector<Eigen::Matrix<double, 2, 1>> hits {};

            cell();
        };

        // define a map keyed by a x coordinate with a value of  std::map.
        // inner map is keyed by a y coordinate with a value of struct type cell.
        typedef std::map<double, std::map<double, cell>> map;
        map mapBase;
    };


#endif

上述三個文件工作時不會出現任何分段錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM