关于arduino上的strcpy和内存

时间:2017-06-11 20:19:54

标签: c++ 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上没有任何内容。

感谢阅读!祝你有愉快的一天:)

1 个答案:

答案 0 :(得分:1)

您缺少的部分是双引号字符串常量同时使用闪存(程序大小)和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。
  • 长双引号字符串可以分成几个相邻的双引号字符串。编译器会为你连接它们。

更新

你可能不需要一个大阵列,如果你可以做你的事情&#34;与碎片。例如,不要制作一个大阵列,以便打印或发送它。只需打印或发送单个部分 - 来自RAM的一些部分(例如,变量)和一些来自闪存的部分(例如,双引号字符串常量)。这节省了RAM(很多!)和处理时间(没有副本或连接)。