本文介绍了关于 Arduino 上的 strcpy 和内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在我的 Arduino Uno 上运行此代码:

I'm running this code on my 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 并且不会使用更多内存.

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). I think I don't understand how strcpy works. But I thought this code would copy ce into cc and wouldn't use more memory.

另一件事:当我在没有 strcpy 的情况下运行代码时,我的 SRAM 中好像什么都没有.

Another thing: When I run the code without the strcpy it's like nothing was in my SRAM.

推荐答案

您缺少的部分是双引号字符串常量同时使用闪存(程序大小)和 RAM.不是因为 strcpy;这是哈佛架构 MCU 上不同类型内存的产物.

The part you're missing is that double-quoted string constants use both flash memory (program size) and RAM. It's not because of strcpy; it's an artifact of the different types of memory on this Harvard Architecture MCU.

为了避免对字符串常量同时使用闪存和 RAM,请使用 F 宏强制它只能从闪存访问:

To avoid using both flash and RAM for string constants, use the F macro to force it to be accessible from flash ONLY:

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 字符数组:

... or define it as a PROGMEM character array:

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 复制.
  • 长双引号字符串可以分解成几个相邻的双引号字符串.编译器会为您连接它们.
  • NOTES:

    • you have to use the strcpy_P variant to copy from flash, not RAM.
    • long double-quoted strings can be broken up into several adjacent double-quoted strings. The compiler will concatenate them for you.
    • 如果你可以用碎片做你的事情",你可能不需要一个大数组.例如,不要制作一个大数组,以便您可以打印或发送它.只需打印或发送各个部分——一些来自 RAM(例如,变量)和一些来自闪存(例如,双引号字符串常量).这节省了 RAM(很多!)和处理时间(没有副本或串联).

      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 (e.g., variables) and some from flash (e.g., double-quoted string constants). This saves RAM (lots!) and processing time (no copies or concatenations).

      这篇关于关于 Arduino 上的 strcpy 和内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-21 03:38