簡體   English   中英

緩沖區被覆蓋

[英]Buffer gets overwritten

我在ESP8266(類似Arduino的板上)上遇到了這個問題,但是這個問題是關於c / c ++的,所以我在這里問這個問題。

我對c / c ++之類的本地語言沒有太多經驗,我面臨一個奇怪的問題,這使我發瘋。 所以我使用的是Wemos D1 mini(ESP8266),它使用一個類調用ConfigManager從eeprom中讀取配置文件。 配置文件的格式為json,所以我使用ArduinoJson解析內容。 我已經在標頭中聲明了StaticJsonBuffer和指向JsonObject指針,如代碼示例所示:

//FILE: ConfigManager.h
#ifndef ConfigManager_H
#define ConfigManager_H

#include <Arduino.h>
#include <ArduinoJson.h>
#include <FS.h>
#include "Logger.h"

class ConfigManager {
public:

    Settings *settings;  

    ConfigManager();

    void read_from_eeprom();

private:

    File configFile;
    JsonObject *json;
    StaticJsonBuffer<200> jsonBuffer;

    void open_file(const char *permission);

    void read_json();

    void recreate_file();

    void create_json();

    void check_success();

    void populate_settings();

    void clean_up();
};

#endif

調用read_from_eeprom函數時,它將打開文件並調用read_json函數:

void ConfigManager::read_json() {
    size_t size = configFile.size();
    Log.verbose("[ConfigManager] Config file size: %d", size);

    std::unique_ptr<char[]> buf(new char[size]);
    configFile.readBytes(buf.get(), size);
    Log.verbose("[ConfigManager] File content: %s", buf.get());

    Log.verbose("[ConfigManager] Parsing json");
    json = &jsonBuffer.parseObject(buf.get());

    Log.notice("[ConfigManager] Json is:");
    json->printTo(Serial);
    Serial.println();
}

接下來是對check_success()的調用

void ConfigManager::check_success() {
    Log.notice("[ConfigManager] Json is:");
    json->printTo(Serial);
    Serial.println();


    bool should_recreate = true;
    if (json->success()) {
        Log.notice("[ConfigManager] Parsed json successfully");

        auto version = json->get<const char*>("version");
        if (version) {
            if (strcmp(version, Settings::current_version) == 0) {
                Log.notice("[ConfigManager] Config version is up2date");
                should_recreate = false;
            } else {
                Log.warning("[ConfigManager] Config version outdated");
            }
        } else {
            Log.warning("[ConfigManager] Invalid config file");
        }
    } else {
        Log.warning("[ConfigManager] Config file is not valid json");
    }

    if (should_recreate) {
        Log.notice("[ConfigManager] Recreating config file");
        recreate_file();
        create_json();
    }

    Log.notice("JSON IS: ");
    json->prettyPrintTo(Serial);

    Log.notice("[ConfigManager] Sucessfully read json");
}

所以我注意到文件內容很好。 例如{"version":"0.2","led_count":"64"}

然后解析json,該json將成功並記錄json對象,該對象又是{"version":"0.2","led_count":"64"}

之后函數返回,並調用check_success ,這再次將json對象的內容打印到日志中,但是這一次似乎已經覆蓋了JsonBuffer,這導致json對象被破壞。 這次,記錄的內容為{"v␂":"0.2","led_count":"64"} (一些奇怪的獨角獸字符隨着源代碼的改變而改變)。 我試圖弄清楚現在已經發生了很多小時,但是我被困住了。 有人可以指出正確的方向來解決這個問題嗎? 謝謝!

完整的日志可以在此處找到,以及ConfigManager.hConfigManager.cpp

*我更願意在評論中寫下來,因為我沒有arduino,也無法驗證我的建議100%有用。 但是我不能使用帶有“我的聲譽”的評論:)。 因此,如果我的回答沒有幫助,請不要按“減號按鈕”。

似乎期間需要使用JSON緩沖區保持原有JSON字符串。

  1. 將JSON字符串在內存中保留足夠長的時間

該庫從不進行內存復制。 這對字符串值有重要意義,這意味着庫將返回指向字符串塊的指針。

例如,假設您像這樣解析[“ hello”,“ world”]:

char [] json =“ [\\” hello \\“,\\” world \\“]”;

StaticJsonBuffer <32>緩沖區;

JsonArray&array = buffer.parseArray(json);

const char * first = array [0];

const char * second = array [1];

在這種情況下,第一個和第二個都是指向原始字符串json內容的指針。 因此,這僅在json仍在內存中時才起作用。

因此,嘗試使std :: unique_ptr buf成為類成員(與StaticJsonBuffer相同)並檢查其工作方式是有道理的。

順便說一句,IMO std :: vector在那里會更適合...而且我不確定unique_ptr是否會正確刪除數組。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM