关于Arduino上的strcpy和内存

About strcpy and memory on Arduino

本文关键字:内存 strcpy 上的 Arduino 关于      更新时间:2023-10-16

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