簡體   English   中英

WifiClient問題-必須是有關局部變量和全局變量的基本C / C ++問題

[英]WifiClient issue - must be a basic C/C++ problem regarding local vs. global variables

在下面的代碼中,執行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上的優化API。

PubSubClient構造函數采用對客戶端的引用。

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

然后獲取指向它的指針以將其存儲為成員。

這意味着它希望引用的Client實例的PubSubClient超過PubSubClient實例的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獲取對客戶端的引用並存儲指針以供以后使用是一種錯誤的模式。 它應該使用指向客戶端的指針,以使其更清楚地了解發生了這種情況。

暫無
暫無

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

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