我正在我的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(很多!)和处理时间(没有副本或串联)。