我正在使用 ESP-IDF 和 FreeRTOS 为 ESP32 设计固件。 我想将传感器的读数转换为字符数组并将其存储在非 volatile 存储中。当获取新读数时,它将被添加到字符数组的前面,将旧读数推到右侧。
我正在以这种方式进行数组操作:
#define MAX_BYTES 100
char oldData[MAX_BYTES];
nvs_get_str( nvsHandle, MASS_STRING_STORE, newData, &required_size);
char newData[15];
sprintf(newData, "%2.2f", Totalmass);
strcat(newData, ",");
printf("new data: %s\n", newData);
printf("strlen oldData: %d\n", strlen(oldData));
printf("strlen newData: %d\n", strlen(newData));
printf("sizeof oldData: %d\n", sizeof(oldData));
printf("i starts from: %d\n", (sizeof(oldData)-strlen(newData2)-1));
for(int i = (sizeof(oldData)-strlen(newData) - 1); i >= 0; i--)
{
oldData [i + strlen( newData )] = oldData[i];
}
for(int i = 0; i < ( strlen(newData) ); i++)
{
oldData[i] = newData[i];
}
nvs_set_str(nvsHandle, MASS_STRING_STORE, oldData);
现在来谈谈我面临的问题:
一旦字符串长度超过 MAX_LENGTH,即 100,代码就会崩溃。
崩溃消息是:
“大师冥想错误:核心 0 发生 panic (CPU0 上的中断 wdt 超时)”
发生崩溃重置后,代码会继续正常工作,直到再次崩溃。 oldData 的 Strlen 打印 104,并保持在 104(我猜最大值应该是 99?)。代码在任务无限循环的一个完整循环完成后立即崩溃。
有人可以指导我这里可能做错了什么吗?如果需要,我可以提供更多信息。
提前致谢!
编辑:
结果发现以下行未被注释:
strcpy(NEWDATA, oldData);
其中 NEWDATA 是一个大小为 20 的数组,该数组明显溢出,因此导致上述问题,现已解决。 我当前面临的另一个问题是我当前阅读的副本附加到数组的末尾。下面我附上了我的日志副本:
new data: 5.00,
strlen oldData: 105
strlen newData: 5
Final Data: 5.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,5.00,
对于 MAX_LENGTH 为 100 的情况,我的数组大小为 105,并且根据新读数的长度保持在 100 以上。但是,我的代码没有崩溃。但最终数据的额外 5 长度始终是我获得的当前读数。 谁能帮我解决这个问题吗?
最佳答案
您正在将 newData 复制到 oldData 中。 strlen() 返回 newData 的长度不包括空终止符。因此,生成的 char 数组可能未终止,导致 nvs_set_str() 调用执行不需要的操作,并且需要足够的时间来触发 WDT。
此外,memcpy() 可能会加速 oldData 的逐字节移位。我说可能是因为我不确定 memcpy 在原位替换上是否正常工作;您需要阅读相关文档。
关于c - 防止c中字符数组溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54803649/