从文件中读取意外变量值 (ESP32)
Unexpected variable values reading from file (ESP32)
本人还在学习Cpp,如有误解请指教
使用 ESP32,我正在尝试将文件读/写到闪存/FFat。这是我创建的方法,它应该从闪存中读取文件并将其加载到 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: %d\n", count);
Serial.printf("Count: %d\n", 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: <myb64string> + <68B of garbage>
为什么 sizeof 没有返回正确的尺寸?
将此字符串加载到缓冲区的正确方法是什么?
Why would sizeof not be returning the proper size?
那是因为sizeof()
有一个非常具体的功能(不是很直观)。它用于 - 编译时 - 查询传递给它的数据类型的大小。调用 sizeof(buffer)
returns 变量类型 buffer
的大小(以字节为单位)。它是一个 unsigned char*
,所以是一个 4 字节的内存地址。这就是你得到的。
What would be the proper way of loading this string into a buffer?
我注意到您希望从您的文件中加载字符串数据,但您没有明确地以零字节终止它。您可能知道,所有 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: %d\n", count);
Serial.printf("Count: %d\n", 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"));
本人还在学习Cpp,如有误解请指教
使用 ESP32,我正在尝试将文件读/写到闪存/FFat。这是我创建的方法,它应该从闪存中读取文件并将其加载到 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: %d\n", count);
Serial.printf("Count: %d\n", 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: <myb64string> + <68B of garbage>
为什么 sizeof 没有返回正确的尺寸?
将此字符串加载到缓冲区的正确方法是什么?
Why would sizeof not be returning the proper size?
那是因为sizeof()
有一个非常具体的功能(不是很直观)。它用于 - 编译时 - 查询传递给它的数据类型的大小。调用 sizeof(buffer)
returns 变量类型 buffer
的大小(以字节为单位)。它是一个 unsigned char*
,所以是一个 4 字节的内存地址。这就是你得到的。
What would be the proper way of loading this string into a buffer?
我注意到您希望从您的文件中加载字符串数据,但您没有明确地以零字节终止它。您可能知道,所有 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: %d\n", count);
Serial.printf("Count: %d\n", 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"));