我目前在 C++ 中遇到向量迭代器的问题。该应用程序在 ESP8266 NodeMCU 微控制器上运行。一旦我调用函数 CWebServer::getAvailableNetworks() (可以在下面找到实现),程序就会崩溃并且我得到以下错误:
User exception (panic/abort/assert)
Abort called
>>>stack>>>
ctx: cont
sp: 3ffffd10 end: 3fffffc0 offset: 0000
3ffffd10: 00000000 00000000 00000000 00000000
3ffffd20: 000000fe 00000000 00000000 00000000
3ffffd30: 00000000 00000000 00000000 b8b1aabc
3ffffd40: 3ffefd60 3fff44cc 00000000 40205e9c
3ffffd50: 3fff451c 00000001 3fff44fc 4020e7ea
3ffffd60: 00000000 00000000 00000000 4020e7fc
3ffffd70: 00000000 3ffffe0c 00000000 4020e219
3ffffd80: 3ffffe04 00000000 00000000 00000000
3ffffd90: 00000000 00000000 00000000 40226fac
3ffffda0: 00000000 40205e9c 3fff451c 40226fbd
3ffffdb0: 3fff44fc 3fff44cc 3fff44fc 402277d8
3ffffdc0: 00000000 00000000 3fff44fc 4020e224
3ffffdd0: 40000000 00000000 00000000 00000000
3ffffde0: 00000000 00000000 00000000 40226fac
3ffffdf0: 3ffefb6c 40205e9c 3fff451c 40226fbd
3ffffe00: 3fff44fc 4022770c 3fff44fc 40227783
3ffffe10: 3fff451c 00000001 3ffffe80 40209f32
3ffffe20: 3ffe90e4 3fffc200 3ffe90f1 4022f3b3
3ffffe30: 3fff43dc 3ffefa4c 3ffe8a37 4020ca74
3ffffe40: 4020ca68 3ffefa4c 3ffe8a37 40205e9c
3ffffe50: 00000001 3ffffe8c 3ffe90e5 4022f3f6
3ffffe60: 3ffffe80 00000001 3ffefa4c 40205e9c
3ffffe70: 00000001 00000001 3ffefa4c 40209915
3ffffe80: 00000000 00000000 00000000 3fff43e8
3ffffe90: 00000001 00000001 00000020 401009b7
3ffffea0: 3fff3d4c 3fffff00 3ffffee0 40205e9c
3ffffeb0: 00000001 00000001 3fff3c54 4021837a
3ffffec0: 3fffff00 3ffef94c 3fff3c54 401000e1
3ffffed0: 3fff3c54 3ffef94c 3fff3c54 40205ed8
3ffffee0: 3fff3d00 0015001f 8015001f 80fe8614
3ffffef0: 3fff3c54 3ffef94c 3ffef90c 40208526
3fffff00: 3fff3d4c 0015001f 00c6a700 00000000
3fffff10: 807a1200 3fff4400 0000005f 80007641
3fffff20: 3ffef94c 00000001 402183ac 00000001
3fffff30: 00000001 00000000 00001388 4020bb3e
3fffff40: 00000000 3fff43a4 3ffef90c 3ffefac8
3fffff50: 00000001 3ffef930 3ffef90c 402093ec
3fffff60: 40218d50 00000000 00001388 4020ca74
3fffff70: 00000000 3fff43a4 3ffe8a37 4020cd39
3fffff80: 3fffdad0 00000000 3ffefa88 402094b0
3fffff90: 3fffdad0 00000000 3ffefa88 4020a140
3fffffa0: feefeffe feefeffe 3ffefa88 4020e454
3fffffb0: feefeffe feefeffe 3ffe8614 40100cb9
<<<stack<<<
ets Jan 8 2013,rst cause:1, boot mode:(3,7)
load 0x4010f000, len 3456, room 16
tail 0
chksum 0x84
csum 0x84
va5432625
~ld
这是导致问题的函数():
void CWebServer::getAvailableNetworks()
{
Serial.println("Get network scan result.");
bool statusSend = false;
try
{
std::string output = "{\"networks\":";
std::vector<sWiFi_Data*> data = CWiFiConnection::getAvailableNetworks();
if(data.size() <= 0)
{
output += "{}";
}
for(std::vector<sWiFi_Data*>::iterator it = data.begin(); it != data.end(); ++it)
{
// This line is for testing. Later on the JSON output will be calculated here from the Vector.
Serial.println(((*it)->SSID).c_str());
}
output += "}";
statusSend = true;
server.send(200, "application/json", output.c_str());
} catch(ScanException& e)
{
statusSend = true;
server.send(425);
} catch(std::exception e)
{
statusSend = true;
server.send(500);
Serial.println();
Serial.println("Unknown Exception while getting the network data:");
Serial.println(e.what());
Serial.println();
}
if(!statusSend) server.send(500);
}
此函数应将网络扫描的结果发送到客户端。网络扫描只需调用函数 WiFi.scanNetworks(true, true); 这是 ESP8266WiFi 的一部分。问题是由 Serial.println(((*it)->SSID).c_str()); 行引起的 一旦程序到达这一点,错误就会出现并且程序崩溃。如果我只是删除这条线并且根本不接触矢量,那么一切都运行良好。所以我假设向量迭代器是这里的坏人。
只是为了完整性:如您所见,向量存储指向“sWiFi_Data”类型结构的指针。这个结构在另一个类(处理 WiFi 连接的类)中定义,它看起来像这样:
struct sWiFi_Data
{
std::string SSID;
std::string BSSID;
int32_t RSSI;
uint8_t channel;
uint8_t encryptionType;
bool isHidden;
};
正如您可能在 CWebServer::getAvailableNetworks() 函数内部注意到的那样,向量是另一个函数 ( CWiFiConnection::getAvailableNetworks(); ) 的结果。此函数位于 CWiFiConnection 类中。它看起来像这样:
std::vector<sWiFi_Data*> CWiFiConnection::getAvailableNetworks()
{
std::vector<sWiFi_Data*> data;
int8_t n = WiFi.scanComplete();
if(n == -1) throw ScanException("Warning: Trying to access network scan data while scan is not completed yet.");
if(n == -2) throw ScanException("Warning: Trying to access network scan, but scan was never triggered.");
if(n >= 0)
{
for(int i = 0; i < n; i++)
{
uint8_t encrytptionType = 0;
switch(WiFi.encryptionType(i)) {
case ENC_TYPE_NONE:
encrytptionType = 1; // None, Open Network
case ENC_TYPE_WEP:
encrytptionType = 2; // WEP
case ENC_TYPE_TKIP:
encrytptionType = 3; // WPA
case ENC_TYPE_CCMP:
encrytptionType = 4; // WPA 2
case ENC_TYPE_AUTO:
encrytptionType = 5; // Auto
default:
encrytptionType = 0; // Unknown
}
sWiFi_Data wifiData;
wifiData.SSID = WiFi.SSID(i).c_str();
wifiData.BSSID = WiFi.BSSIDstr(i).c_str();
wifiData.RSSI = WiFi.RSSI(i);
wifiData.channel = WiFi.channel(i);
wifiData.encryptionType = encrytptionType;
wifiData.isHidden = WiFi.isHidden(i);
data.push_back(&wifiData);
}
WiFi.scanDelete();
return data;
} else
{
throw ScanException("Warning: No networks found.");
}
}
顺便说一句:ScanException 只是我写的一个通用异常。没什么特别的,所以我认为我不需要在此处包含代码。
只是为了澄清一下,通信过程如下所示:
- 客户端发送请求以扫描网络。
- 服务器只调用方法: WiFi.scanNetworks(true, true); (参数:bool async,bool showHidden)
- 因为扫描是异步的,所以客户端通过向服务器发送请求来检查结果。
- 服务器总是通过调用 CWebServer::getAvailableNetworks() 函数(我们的问题函数)来响应这些请求。
- 理论上,如果结果还没有,这个函数应该用代码 425(“还没准备好”)回复,如果扫描完成,应该将所有可用网络的数据作为 JSON 发送(这将在行的地方实现Serial.println(((*it)->SSID).c_str()); 目前是。
顺便说一句:我还尝试在控制台内输出向量的大小。这工作正常。所以向量内肯定有值。
希望任何人都可以在这里帮助我。非常感谢。
- 詹尼斯
ps.:可以在此处找到包含 ESP8266 网络扫描示例的文档:https ://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/scan-examples.html