首页 > 解决方案 > 防止字符数组在c中溢出

问题描述

我正在使用 ESP-IDF 和 FreeRTOS 为 ESP32 设计固件。我想将传感器的读数转换为 char 数组并将其存储在非易失性存储中。当获取新读数时,将其添加到 char 数组的前面,将旧读数推到右侧。

我正在以这种方式进行数组操作:

#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 恐慌(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,

对于 100 的 MAX_LENGTH,我的数组大小为 105,并且根据我的新读数的长度保持超过 100。但是,我的代码没有崩溃。但是我最终数据的额外 5 长度始终是我得到的当前读数。谁能帮我解决这个问题?

标签: carraysstringfreertosesp32

解决方案


您正在将 newData 复制到 oldData 中。strlen() 返回 newData 的长度,不包括空终止符。因此,您生成的 char 数组可能未终止,从而导致 nvs_set_str() 调用执行不希望的操作,并花费足够的时间来触发 WDT。

此外,您的 oldData 逐字节移位可能会被 memcpy() 加速。我说可能是因为我不确定 memcpy在原位替换上是否正常工作;您需要阅读相关文档。


推荐阅读