简体   繁体   English

关于 Arduino 上的 strcpy 和内存

[英]About strcpy and memory on Arduino

I'm running this code on my Arduino Uno :我在我的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:

}

So I wanted to see how much memory this was taking.所以我想看看这占用了多少内存。 And I was surprised that it was not 300 as I expected, but 300 + len(cc).我很惊讶它不是我预期的 300,而是 300 + len(cc)。 I think I don't understand howstrcpy works.我想我不明白strcpy是如何工作的。 But I thought this code would copy ce into cc and wouldn't use more memory.但我认为这段代码会将ce复制到cc并且不会使用更多内存。

Another thing: When I run the code without the strcpy it's like nothing was in my SRAM.另一件事:当我在没有 strcpy 的情况下运行代码时,就像我的 SRAM 中什么都没有。

The part you're missing is that double-quoted string constants use both flash memory (program size) and RAM.您缺少的部分是双引号字符串常量同时使用闪存(程序大小)和 RAM。 It's not because of strcpy ;这不是因为strcpy it's an artifact of the different types of memory on this Harvard Architecture MCU.它是哈佛架构 MCU 上不同类型内存的产物。

To avoid using both flash and RAM for string constants, use the F macro to force it to be accessible from flash ONLY:为了避免对字符串常量同时使用闪存和 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());
}

... or define it as a PROGMEM character array: ...或将其定义为 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());
}

NOTES:注意事项:

  • you have to use the strcpy_P variant to copy from flash, not RAM.您必须使用strcpy_P变体闪存复制,而不是RAM 复制。
  • long double-quoted strings can be broken up into several adjacent double-quoted strings.长双引号字符串可以分解成几个相邻的双引号字符串。 The compiler will concatenate them for you.编译器将为您连接它们。

UPDATE:更新:

You may not need one big array if you can do your "thing" with the pieces.如果你可以用这些碎片做你的“事情”,你可能不需要一个大阵列。 For example, don't make one big array so you can print or send it.例如,不要制作一个大数组,以便您可以打印或发送它。 Just print or send the individual pieces -- some pieces from RAM (eg, variables) and some from flash (eg, double-quoted string constants).只需打印或发送单个片段——一些片段来自 RAM(例如,变量),一些来自闪存(例如,双引号字符串常量)。 This saves RAM (lots!) and processing time (no copies or concatenations).这节省了 RAM(很多!)和处理时间(没有副本或串联)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM