有效的问题 - 关于本地变量和全局变量,必须是基本的C/C 问题



在下面的代码中,我在执行mqtt.publish()时会崩溃,但是只有当wificLient是局部变量时,才会发生这种情况 - 如果wificLient是全局变量,则问题消失了。

我认为不需要了解基础库。

关于指针/垃圾收集或不引起这一点的原因,必须有一个微妙的。我一直在做C#多年,在C 方面的经验少得多。

#include <PubSubClient.h>
#include <WiFiClient.h>
void mqttSubs(char* topic, byte* payload, unsigned int length) {}   

// if this line is moved inside setup() then the call to publish will crash
WiFiClient wifiClientGlobal;
PubSubClient mqttClient;
void setup() {
  //WiFiClient wifiClientGlobal;
  mqttClient = PubSubClient(mqttServer, mqttPort, mqttSubs, wifiClientGlobal);
  mqttClient.connect("ESP8266Client", mqttUser, mqttPassword );
}
void loop() {
  mqttClient.publish("repro/global", "sending message");
}

任何人都可以阐明吗?

没有太多的升华,只是(imo)pubsubclient上的(imo)不良文档和次级api。

pubsubclient构造函数参考客户端。

PubSubClient(IPAddress, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client);

然后将指针用于将其存储为会员。

这意味着它期望Client实例需要参考以超过PubSubClient实例。

没有发生垃圾收集。只是,如果您声明具有自动存储持续时间的对象,那么它将在范围范围内被销毁。

因此,原因本质上是这样:

struct B{
    int num;
};
struct A{
    A(B& param){
        m_b = &param;
    }
    B* m_b;
};
A obj;
setup()
{
    B b;
    obj = A(b); 
    //after this function ends b is considered destroyed
}
loop()
{
    //the following line accesses a member of the already destroyed object
    print(obj.m_b->num);
}

此测试案例基本上表现出与您的代码相同的"自由使用"(可能不会崩溃,但确实包含相同的未定义行为)。

我认为,PubSubClient参考客户端并存储指针以供以后使用是不良模式。应该向客户指针,以使这是发生的事情。

相关内容

  • 没有找到相关文章

最新更新