簡體   English   中英

如何從 C/C++ 函數返回一個 const char *?

[英]How to return a const char * from a C/C++ function?

我有以下 C++ 函數,它從閃存中讀取一個字符串並返回它。 我想避免使用String類,因為這是一個Arduino,我已經被告知,為Arduino的String類是越野車

const char* readFromFlashMemory()
{
    char s[FLASH_STOP_ADDR-FLASH_START_ADDR+2];
    memset(s, (byte)'\0', FLASH_STOP_ADDR-FLASH_START_ADDR+2);
    unsigned short int numChars = 0;

    for (int i = FLASH_START_ADDRESS; i <= FLASH_STOP_ADDRESS; i++)
    {
        byte b = EEPROM.read(i);
        if (b == (byte)'\0')
            return s;
        else
            s[numChars++] = (char)b;
    }
}

這個功能似乎有效。 但是調用方法返回一個空字符串。 我是否不允許返回指向此函數堆棧上的字符數組的指針? 我應該如何編寫此函數以便調用函數接收我想傳遞給它的值的最佳/最慣用的方法?

這些評論可能會讓您誤入歧途,或者充其量會使您感到困惑。 讓我用一些選項來分解它。

首先,問題正如你所說:當函數從堆棧中彈出給調用者時,你返回的地址的數組不再存在。 忽略這一點會導致未定義行為。

以下是一些選項以及一些討論:

  1. 調用者擁有緩沖區

    void readFromFlashMemory(char *s, size_t len)

    優點是調用者可以選擇如何分配這塊內存,這在嵌入式環境中很有用。

    請注意,為了方便起見,您也可以選擇從此函數返回s ,或傳達一些額外的含義。

    對我來說,如果我在 Arduino 等嵌入式環境中工作,這將是我 100% 的偏好。

  2. 使用std::stringstd::vector或類似的

    std::string readFromFlashMemory()

    如果您不關心分配開銷和其他潛在問題(例如隨着時間的推移出現碎片),這可能是您執行此操作的方式。

  3. 自己分配內存

    char* readFromFlashMemory()

    如果您想確保分配的內存大小正好合適,那么您可能會先讀入本地緩沖區,然后分配內存並進行復制。 std::string或其他處理堆內存的解決方案相同的內存注意事項。

    這種形式還具有調用者的噩夢般的屬性,負責管理返回的指針並最終調用delete[] 這是非常不可取的。 這也很常見。 :(

  4. 如果絕對必須,返回動態分配的內存的更好方法

    std::unique_ptr<char[]> readFromFlashMemory()

    與#3 相同,但指針是安全管理的。 需要 C++11 或更高版本。

  5. 使用靜態緩沖區

    const char* readFromFlashMemory() { static char s[FLASH_STOP_ADDR-FLASH_START_ADDR+2]; // ... return s; }

    一般不以為然。 特別是因為這種類型的模式會在多線程環境中導致令人討厭的問題。

    人們大多選擇這種方法是因為他們很懶惰並且想要一個簡單的界面。 我想一個好處是調用者不必知道什么大小的緩沖區是可以接受的。

  6. 使用內部緩沖區創建自己的類

    class FlashReader { public: const char* Read(); private: char buffer[FLASH_STOP_ADDR-FLASH_START_ADDR+2]; };

    這更像是一個冗長的解決方案,並且可能開始聽起來像是過度設計。 但它確實結合了 #1 和 #5 的最佳部分。 也就是說,您可以獲得緩沖區的堆棧分配,您不需要知道大小,並且函數本身不需要額外的參數。

    如果您確實想要一個靜態緩沖區,那么您可以只定義該類的一個靜態實例,但不同之處在於代碼中的明確意圖。

暫無
暫無

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

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