【问题标题】:Use large arrays inside c++ class在 C++ 类中使用大数组
【发布时间】:2021-08-06 22:38:33
【问题描述】:

这就是我的班级的样子。我的代码编译成功,但是当我运行它时,它崩溃并停止。

class Explore{

    public:

        Explore(ros::NodeHandle &nh, tf2_ros::Buffer &buffer);

    private: 

        
        bool is_frontier(size_t mx, size_t my);
        void explore_level_three();
        void go_to_cell(size_t mx, size_t my);
        void publish_markers_array();
        void publish_markers();
        
        
        costmap_2d::Costmap2DROS* global_costmap, *local_costmap;
        costmap_2d::Costmap2D* global_costmap_, *local_costmap_;
        
        ros::NodeHandle nh_;
        ros::Publisher frontier_array_pub, frontier_pub; 

        vector<pair<size_t, size_t> >frontiers;
        
        string global_frame, robot_base_frame;
        unsigned char *global_og;

        size_t size_x, size_y;  
        double init_wx, init_wy; 
        
        int vis[4001][4001], frontier_vis[4001][4001] ; 

};

当我将vis[4001][4001], frontier_vis[4001][4001]; 更改为vis[500][500], frontier_vis[500][500]; 时,代码运行成功。

这是我的main 函数-

int main(int argc, char** argv) {

    ros::init(argc, argv, "explore_node");

    ros::NodeHandle nh("explore_node"); 

   
    tf2_ros::Buffer buffer(ros::Duration(10));
    tf2_ros::TransformListener tf(buffer);
    
    
    Explore explore_one(nh, buffer);

   
    return 0;
} 

我该如何解决这个问题?

【问题讨论】:

标签: c++ arrays class


【解决方案1】:

我该如何解决这个问题?

可用于自动对象的内存通常非常有限。因此,您必须动态分配所有大对象。否则,您的变量可能会占用为自动对象保留的所有内存,从而导致...堆栈溢出。

如果类的所有实例都是动态分配的,那么拥有巨大的成员变量将不是问题,但由于这种限制难以实施,通常最好不要拥有巨大的成员变量。

您的数组visfrontier_vis 很大。简单的解决方案:使用std::vector

【讨论】:

  • @eeerokia since that restriction is hard to enforce - 你为什么这么说?
  • @skpro19 因为没有允许仅在动态内存中创建对象的语言机制。当然,您可以将构造函数设为私有,并提供返回唯一指针的自定义函数,但编写所有这些函数可能是很多样板文件,如果您只是没有使类变得如此庞大,那么这些样板文件将是不必要的。
  • @skpro19 避免巨大成员的一种方法是动态分配成员,最好使用library container 来处理内存管理。 Here is a simple matrix class 提供了一个动态分配的、自我管理的结构,在外部世界看起来就像一个二维数组。
【解决方案2】:

很可能您正在堆栈上创建Explore 的对象,这将提供Segmentation Fault。您应该在堆上动态声明对象

int main() {
    Explore * obj = new Explore(...);
    delete obj; //since obj is on the heap, 
                //you have to take care of delete. using smart pointers 
                //like std::unique_ptr can efficiently handle the lifetime
    return 0;
}

而不是

int main() {
    Explore obj(...);
    return 0;
}

不过,std::vector 会更好。

【讨论】:

  • 您正在泄漏内存。如果你使用 unique_ptr 就不会
  • @skpro19 当你用new分配一些内存时,你需要用delete释放它。但是如果你使用std::unique_ptr,这会自动发生。
  • @skpro19 当您从堆中分配存储空间时,通常会降低性能。系统必须找到足够大的空闲存储空间。要从堆栈中获取内存,通常会移动一个指针。使用动态分配的对象时,您也可能会受到性能损失,因为它们可能分散在整个内存中,从而更难缓存它们。由于它的大小,这对你的类来说应该不是问题。
  • @skpro19 2 个主要原因是:您将泄漏内存(并且可能会耗尽它)并且不会运行泄漏对象的析构函数。
  • @user4581301 程序运行时可能内存不足。特别是考虑到 OP 分配了巨大的块。
猜你喜欢
  • 2016-05-02
  • 2014-02-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-25
相关资源
最近更新 更多