【问题标题】:About strcpy and memory on Arduino关于 Arduino 上的 strcpy 和 memory
【发布时间】:2017-06-11 20:19:53
【问题描述】:

我正在我的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 中什么都没有。

【问题讨论】:

  • strcpy 接受 两个 参数,而不是三个。
  • 是的,我知道,我只是在复制粘贴时失败了。一开始我用的是strncopy。

标签: c++ arduino


【解决方案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。
  • 长的双引号字符串可以分解成几个相邻的双引号字符串。编译器将为您连接它们。

更新:

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

【讨论】:

  • 感谢您的回答!但我想知道我是否有一个返回 char 数组的函数。我想把这个 char 数组复制到 cc 中,strcpy 还是有同样的问题?
  • @Syndorik,请参阅上面的更新。不,我不这么认为,但我看不到你建议的代码。我怀疑你的函数应该返回一个在 RAM 中的 char 数组,比如cc。您可以将 cc 设为全局,以便函数可以修改它,而不是在整个地方都有额外的 RAM char 数组副本/片段。如果您想要更具体的回复,请编辑您的问题以添加一些内容。如果这个答案对你有用,请按绿色的“接受”按钮(复选标记?)。
猜你喜欢
  • 2018-06-21
  • 2015-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-08
  • 2018-06-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多