[英]Unexpected variable values reading from file (ESP32)
I am still learning Cpp, so please advise if I am misunderstanding here.我还在学习Cpp,所以如果我在这里误解,请指教。
Using an ESP32, I am trying to read / write files to Flash / FFat.使用 ESP32,我正在尝试将文件读/写到 Flash / FFat。 This is the method I have created which should read a file from flash and load it into PSRAM:
这是我创建的方法,它应该从 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: %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;
}
The problem is that I get the contents of my b64 data file, with the addition of several extra bytes of data globbed on the end.问题是我得到了我的 b64 数据文件的内容,最后添加了几个额外的数据字节。
Calling the method with:调用方法:
Serial.printf("Got: %s", storage_read("/frame/testframe-000.b64"));
I get the output:我得到 output:
Bytes: 684
字节:684
Count: 4数量:4
Got: <myb64string> + <68B of garbage>得到:<myb64string> + <68B 垃圾>
Why would sizeof not be returning the proper size?为什么sizeof不会返回正确的大小?
What would be the proper way of loading this string into a buffer?将此字符串加载到缓冲区中的正确方法是什么?
Why would sizeof not be returning the proper size?
为什么 sizeof 不会返回正确的大小?
That's because sizeof()
has a very specific function (not very intuitive).那是因为
sizeof()
有一个非常具体的 function (不是很直观)。 It is used - compile time - to query the size of the data type passed to it.它用于 - 编译时 - 查询传递给它的数据类型的大小。 Calling
sizeof(buffer)
returns the size, in bytes, of the type of variable buffer
.调用
sizeof(buffer)
返回变量buffer
类型的大小(以字节为单位)。 It's an unsigned char*
, so a 4-byte memory address.这是一个
unsigned char*
,所以是一个 4 字节的 memory 地址。 So that's what you get.所以这就是你得到的。
What would be the proper way of loading this string into a buffer?
将此字符串加载到缓冲区中的正确方法是什么?
What I noticed is that you're expecting to load string data from your file, but you don't explicitly terminate it with a zero byte.我注意到您希望从文件中加载字符串数据,但您没有明确地用零字节终止它。 As you probably know, all C strings must be terminated with a zero byte.
您可能知道,所有 C 字符串必须以零字节结束。 Data that you load from the file most likely doesn't have one (unless you took extra care to add it while saving).
您从文件中加载的数据很可能没有(除非您在保存时特别注意添加它)。 So when you read a string from a file sized N bytes, allocate a buffer of N+1 bytes, load the file into it and terminate it with a zero.
因此,当您从一个大小为 N 字节的文件中读取字符串时,分配一个 N+1 字节的缓冲区,将文件加载到其中并以零终止。 Something like this:
像这样的东西:
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;
}
And since you're returning a heap-allocated buffer from your function, take extra care to remember to delete it in caller when finished.而且由于您要从 function 返回一个堆分配的缓冲区,因此请特别注意记住在完成后在调用者中删除它。 This line in your code will leak the memory:
您代码中的这一行将泄漏 memory:
Serial.printf("Got: %s", storage_read("/frame/testframe-000.b64"));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.