防止字符数组在c

时间:2019-02-21 09:32:31

标签: c arrays string freertos esp32

我正在使用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中断超时)”

发生崩溃重置后,代码将继续正常运行,直到再次崩溃。 Strold of oldData打印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个长度始终是我得到的当前读数。 有人可以帮我吗?

4 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

“ CPU0的中断wdt超时”非常清楚。您有看门狗超时重置。反过来,这意味着您的代码太慢,或者您没有从代码中的任何地方踢狗。

在嵌入式系统中使用stdio.h几乎是一个很大的禁忌,因为它极其缓慢且占用资源。

另一个例子,如果优化不好或被禁用,for(int i = 0; i < ( strlen(newData) ); i++)可能会给出非常慢的代码,应将其替换为size_t length = strlen(newData); for(int i=0; i<length; ...

最后,如果要写入闪存,驱动程序需要先擦除闪存,这需要很长时间。

答案 2 :(得分:0)

所有评论和答案都受到高度赞赏,我将考虑所有观点以使我的代码变得更好。

但是,事实证明我错误地取消了代码中的注释,该注释将我的最终数组复制到一个较小的数组中。这就是为什么我的代码不断崩溃的原因。到目前为止,该问题已解决。一旦实现了代码的其他功能,我将在稍后讨论该代码的时间消耗和优化。

谢谢!!

答案 3 :(得分:0)

由于修改了OP,添加了第二个答案。

首先,最好显示工作代码。这段话表明它不会编译:

nvs_get_str( nvsHandle, MASS_STRING_STORE, newData, &required_size);
char newData[15];

关于您的问题:您的printf()输出使我怀疑您是否真的在这里处理字符串数据。如果不是,则不要使用nvs_get_str(),因为它遇到空字符后将停止读取NVS。同样,如果您在非字符串数据上使用strlen(),则可能无法正常工作。

如果要存储和处理非字符串数据,请使用nvs_get_blob()进行检索,并使用存储功能将其复制到程序中。