ESP8266调用printIPs函数致Free Heap递减触发致命异常求助
问题解决:ESP8266调用printIPs后内存泄漏导致崩溃
核心原因
你调用wifi_softap_get_station_info()获取连接设备链表后,未手动释放该链表占用的动态内存。ESP8266的RTOS环境中,该函数会在堆上分配内存存储station信息,每次调用若不释放,就会持续占用内存导致泄漏,堆空间逐步耗尽后,会触发StoreProhibitedCause异常(通常是访问了空指针或非法内存地址)。
修改后的代码
void printIPs() { unsigned char softap_stations_cnt = 0; struct station_info *stat_info; struct ip4_addr *IPaddress; uint32 uintaddress; byte mordisco; softap_stations_cnt = wifi_softap_get_station_num(); stat_info = wifi_softap_get_station_info(); if (stat_info != NULL) { Serial.print("Finding number of Station IPs connected: "); Serial.println(softap_stations_cnt); Serial.println("Printing the last byte of the Station IPs connected:"); display.print(" - IPs: "); while (stat_info != NULL) { IPaddress = &stat_info->ip; uintaddress = IPaddress->addr; // 修正IP字节序:ip4_addr.addr是网络大端序,ESP8266是小端架构,取最后一字节用&0xFF mordisco = (uintaddress & 0xFF); Serial.print(mordisco); Serial.print(" "); display.print(mordisco); display.print(" "); stat_info = STAILQ_NEXT(stat_info, next); } // 关键:释放链表占用的堆内存 wifi_softap_free_station_info(); } }
额外说明
- IP字节序修正:原代码中
(uintaddress >> 24)逻辑错误,因为ip4_addr.addr采用网络大端序存储,而ESP8266是小端架构,获取IP最后一字节需用uintaddress & 0xFF,否则打印的是IP的第一个字节。 - 内存释放时机:必须在遍历完整个链表后调用
wifi_softap_free_station_info(),该函数会一次性释放链表所有节点的内存,不可在遍历过程中单独释放节点。 - 异常关联:堆内存耗尽后,后续内存分配会失败,可能产生空指针,访问空指针就会触发
StoreProhibitedCause异常,与你观察到的堆内存逐步减少的现象完全匹配。
内容的提问来源于stack exchange,提问作者Ilmanowar
相关产品推荐
相关产品推荐

