为什么这个程序会崩溃或挂起?

问题描述 投票:0回答:1

以下代码崩溃或挂起,直到内存耗尽:

#include <iostream>
#include <functional>
using namespace std::placeholders;

struct Goal {float x; float y;};

class Boxbot 
{
public:
    Boxbot(Goal cgoals[]=0) 
    {
        for (int i=0;i<3;i++) { cgoals_[i]=cgoals[i]; }
        for (int i=0;i<3;i++) { callbacks(i); }
        
    }
private:
    //Declare member function
    bool check_goal(Goal gl) 
    {
        if (std::sqrt(std::pow(gl.x,2)+std::pow(gl.y,2))<2) {return true;}
        else {return false;}
    }
    //Creating a functor : function object
    struct Callback 
    {
        void operator() (int i) const {
            Boxbot b;
            b.bgoals[i]=b.check_goal(b.cgoals_[i]);
            std::printf("%s is %i\n",b.topicns[i].data(),b.bgoals[i]);
        }
    } callbacks;
    
    //Declare member variables
    bool bgoals[3]={false,false,false};
    Goal cgoals_[3];
    std::string topicns[3]={"robot_1","robot_2","robot_3"};
};

int main() 
{
    Goal cgoals[3] = {{0.3,0.6},{0.9,1.2},{1.5,1.8}};
    Boxbot boxbot(cgoals);
    return 0;
}

结果应该如下,但是卡住了。

robot_1 is 1
robot_2 is 1
robot_3 is 0

我在这里想做的就是这一部分:

for (int i=0;i<3;i++) { callbacks(i); }
。换句话说,我想在私有中创建一个函数对象并在公共中访问它以传递来自 main 的参数。

当我将它们公开时,check_goal()Callback本身工作正常,所以我认为问题是函子callbacks在公共场合不能很好地工作......但我不知道为什么。

我在 C++ shell 版本 14、17、20 上进行了测试。

c++ class functor
1个回答
1
投票

您有两个问题,一个导致另一个。

第一个问题是你有

Boxbot
创作的无限递归。

main
函数中,您创建一个
Boxbot
对象。

Boxbot
课程中

struct Callback 
{
    void operator() (int i) const {
        Boxbot b;   // Here you create another Boxbot object
        b.bgoals[i]=b.check_goal(b.cgoals_[i]);
        std::printf("%s is %i\n",b.topicns[i].data(),b.bgoals[i]);
    }
} callbacks;

operator()
函数中,您创建另一个
Boxbot
对象。这个运算符在
Boxbot
构造函数中被调用。因此,每个
Boxbot
对象创建都会导致另一个 Boxbot` 对象创建。永远,或者直到出现堆栈溢出。


第二个问题出现,因为构造函数默认参数为空指针(

Goal cgoals[]=0
作为参数实际上是
 Goal* cgoals=0
),当您复制
Goal
对象时,您的递归对象创建将具有空指针访问权限。这会导致未定义的行为并可能导致崩溃。


我不太确定为什么你有

Callback
callbacks
对象。你的构造函数可能只是:

Boxbot(Goal* cgoals = nullptr) 
{
    if (cgoals == nullptr)
    {
        return;
    }

    for (size_t i = 0; i < 3; ++i)
    {
        cgoals_[i] = cgoals[i];
        bgoals[i] = check_goal(cgoals_[i]);
    }
}

没有递归,没有空指针访问,只需要一个循环。

© www.soinside.com 2019 - 2024. All rights reserved.