简体   繁体   English

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM