簡體   English   中英

關於 Arduino 上的 strcpy 和內存

[英]About strcpy and memory on Arduino

我在我的Arduino Uno上運行這個代碼:

#include <stdlib.h>


#include <Arduino.h>
#include <SoftwareSerial.h>
#include <MemoryFree.h>


void setup() {
  Serial.begin(9600);
  char cc[300];
  char* ce = "Bonjour ca va et toi ?Bonjour ca va et toi ?Bonjour ca va et toi ?Bonjour ca va et toi ?";
  strcpy(cc, ce, 300);
  Serial.println(getFreeMemory());
}

void loop() {
  // Put your main code here, to run repeatedly:

}

所以我想看看這占用了多少內存。 我很驚訝它不是我預期的 300,而是 300 + len(cc)。 我想我不明白strcpy是如何工作的。 但我認為這段代碼會將ce復制到cc並且不會使用更多內存。

另一件事:當我在沒有 strcpy 的情況下運行代碼時,就像我的 SRAM 中什么都沒有。

您缺少的部分是雙引號字符串常量同時使用閃存(程序大小)和 RAM。 這不是因為strcpy 它是哈佛架構 MCU 上不同類型內存的產物。

為了避免對字符串常量同時使用閃存和 RAM,請使用 F 宏強制它只能從閃存訪問:

void setup() {
  Serial.begin(9600);
  char cc[300];
  strcpy_P(cc, (const char *) F("Bonjour ca va et toi ?Bonjour ca va et toi ?"
                                "Bonjour ca va et toi ?Bonjour ca va et toi ?") );
  Serial.println(getFreeMemory());
}

...或將其定義為 PROGMEM 字符數組:

const char ce[] PROGMEM =
        "Bonjour ca va et toi ?Bonjour ca va et toi ?"
        "Bonjour ca va et toi ?Bonjour ca va et toi ?";

void setup() {
  Serial.begin(9600);
  char cc[300];
  strcpy_P(cc,ce);
  Serial.println(getFreeMemory());
}

注意事項:

  • 您必須使用strcpy_P變體閃存復制,而不是RAM 復制。
  • 長雙引號字符串可以分解成幾個相鄰的雙引號字符串。 編譯器將為您連接它們。

更新:

如果你可以用這些碎片做你的“事情”,你可能不需要一個大陣列。 例如,不要制作一個大數組,以便您可以打印或發送它。 只需打印或發送單個片段——一些片段來自 RAM(例如,變量),一些來自閃存(例如,雙引號字符串常量)。 這節省了 RAM(很多!)和處理時間(沒有副本或串聯)。

暫無
暫無

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

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