从文件读取意外的变量值(ESP32)



我还在学习Cpp,所以如果我在这里误解了,请告诉我。

使用ESP32,我正在尝试读/写文件到Flash/FFat。这是我创建的方法,它应该从flash读取文件并将其加载到PSRAM中:

unsigned char* storage_read(char* path) {
File file = FFat.open(path);
if(!file) {
Serial.println("no file");
return 0x00;
}
int count = file.size();
unsigned char* buffer = (unsigned char*)ps_malloc(count);
Serial.printf("Bytes: %dn", count);
Serial.printf("Count: %dn", sizeof(buffer));
for (int i = 0; i < count; i++) {
buffer[i] = (unsigned char)file.read();
}
file.close();
return buffer;
}

问题是我得到了我的b64数据文件的内容,并在末尾添加了几个额外的数据字节。

用:

调用方法
Serial.printf("Got: %s", storage_read("/frame/testframe-000.b64"));

我得到了输出:

Bytes: 684
Count: 4
Got: <+ <68B的垃圾>

为什么sizeof不能返回正确的大小?

将这个字符串加载到缓冲区的正确方法是什么?

为什么sizeof不能返回正确的大小?

这是因为sizeof()具有非常特定的功能(不是很直观)。它在编译时用于查询传递给它的数据类型的大小。调用sizeof(buffer)返回变量buffer类型的大小(以字节为单位)。它是一个unsigned char*,所以是一个4字节的内存地址。这就是你得到的。

将这个字符串加载到缓冲区的正确方法是什么?

我注意到的是,你期望从文件中加载字符串数据,但你没有显式地用零字节终止它。您可能知道,所有C字符串都必须以零字节结束。从文件加载的数据很可能没有一个(除非您在保存时特别注意添加它)。因此,当你从一个大小为N字节的文件中读取字符串时,分配一个N+1字节的缓冲区,将文件加载到其中,并以零结束。像这样:

unsigned char* storage_read(char* path) {
File file = FFat.open(path);
if(!file) {
Serial.println("no file");
return 0x00;
}
int count = file.size();
unsigned char* buffer = (unsigned char*)ps_malloc(count + 1); //< Updated
Serial.printf("Bytes: %dn", count);
Serial.printf("Count: %dn", sizeof(buffer));
for (int i = 0; i < count; i++) {
buffer[i] = (unsigned char)file.read();
}
buffer[count] = 0; //< Added
file.close();
return buffer;
}

由于您从函数返回堆分配的缓冲区,因此要格外注意,记住在完成调用时将其删除。代码中的这一行将泄漏内存:

Serial.printf("Got: %s", storage_read("/frame/testframe-000.b64"));

最新更新