【问题标题】:Operator new for ArduinoArduino 新操作员
【发布时间】:2013-04-29 08:39:25
【问题描述】:

有人告诉我(特别是在 an answer to C++ Standard Library on Arduino 和 Stack Overflow 问题 C++ string and Arduino String. How to combine them?)中)Arduino 编译器没有实现 new 运算符。但是,我已经为使用它的 Arduino(在 Arduino IDE 中)编写了一个程序,它运行良好。

void setup() {
    Serial.begin(9600);
}

void loop() {
    char* array;
    char c;
    unsigned arraySize;

    Serial.write("Enter a 1 digit number.\n");

    do {
        c = Serial.read();
    } while(c < '0' or c > '9');
    arraySize = c-'0';

    Serial.write("You wrote ");
    Serial.write(c);
    Serial.write(".\n");
    Serial.write("Now enter ");
    Serial.write(c);
    Serial.write(" lower-case letters.\n");

    array = new char[arraySize];

    for (unsigned i = 0; i < arraySize;) {
        array[i] = Serial.read();
        if (array[i] >= 'a' and array[i] <= 'z')
            i++;
    }

    Serial.write("You entered: ");

    for (unsigned i = 0; i < arraySize; i++) {
        Serial.write(array[i]);
        Serial.write(" ");
    }
    Serial.write("\n");
}

这里是一个示例输出来展示它的功能:

Enter a 1 digit number.
You wrote 5.
Now enter 5 lower-case letters.
You entered: h e l l o
Enter a 1 digit number.
You wrote 9.
Now enter 9 lower-case letters.
You entered: w a s s u p m a n
Enter a 1 digit number.
You wrote 9.
Now enter 9 lower-case letters.
You entered: h o w y a d o i n
Enter a 1 digit number.
You wrote 4.
Now enter 4 lower-case letters.
You entered: c o o l
Enter a 1 digit number.
You wrote 7.
Now enter 7 lower-case letters.
You entered: i t w o r k s
Enter a 1 digit number.

那为什么我一直听到这个?这些人是错的,还是我只是误解了他们的意思?

【问题讨论】:

  • 军队里常说,如果地图与地形不匹配,请相信地形。

标签: c++ arduino new-operator arduino-ide


【解决方案1】:

newdelete 被定义为 Arduino 发行版的一部分: /usr/share/arduino/hardware/arduino/cores/arduino/new.h:

/* Header to define new/delete operators as they aren't provided by avr-gcc by default
   Taken from http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=59453 
 */
#ifndef NEW_H
#define NEW_H

#include <stdlib.h>

void * operator new(size_t size);
void operator delete(void * ptr); 

__extension__ typedef int __guard __attribute__((mode (__DI__)));

extern "C" int __cxa_guard_acquire(__guard *);
extern "C" void __cxa_guard_release (__guard *);
extern "C" void __cxa_guard_abort (__guard *); 

extern "C" void __cxa_pure_virtual(void);

#endif

new.h 包含在 Printable.h 中,因此您可以在 Arduino 基本包含中获得它。这些运算符在 AVR Libc 中没有定义。我对这些设计选择的解释:Libc 的人认为这是一个坏主意,而 Arduino 的人则只关心易用性:如果你想要 newdelete,请拥有它们。

【讨论】:

    【解决方案2】:

    正如您所展示的,newdelete 原则上在 Arduino 上工作。问题是您的 Arduino 有 2K 的 RAM 用于全局变量、堆栈和堆组合,因此您为它编写的任何实质性程序都必须高度了解内存使用情况。

    因此,对于像这样的嵌入式系统,通常最好使用静态分配(或在某些情况下可能是按类动态分配)而不是通用动态分配:对于简单的程序,您不要需要动态分配,对于复杂的程序,你负担不起

    【讨论】:

      【解决方案3】:

      仅仅因为平台没有预定义operator new() 并不意味着不能定义它。在您的代码中,大概有人已经为分配函数编写了一个定义,所以一切都很好。

      (我假设您熟悉 new 表达式和分配函数之间的区别,它被混淆地称为 operator new()。)


      这是一个小示例定义,应该可以让一个短程序运行:

      char buf[1024];
      char * cur = buf;
      
      void * operator new(std::size_t n)
      {
          char * res = cur;
          std::size_t inc = (n + 15) / 16 * 16;
      
          if (std::distance(cur, buf + sizeof(buf)) < inc)
              throw std::bad_alloc();
      
          cur += inc;
      
          return res;
      }
      
      void operator delete(void * p) noexcept
      {
      }
      

      这显然会很快耗尽内存。

      【讨论】:

      • 但我没有定义它。而且我没有使用任何特殊的库。因此,如果 operator new 在所有形式中都有有效的定义,那与在 Arduino 平台上“实施”的 new 不一样吗?这些人说 Arduino 不支持 newdelete 是什么意思?显然它们有效,那么有什么问题?
      • 我喜欢这被称为“婴儿榜样”。
      • 这个例子有两个问题:1:试图在嵌入式系统上使用异常,2:假设Arduino有一个std命名空间(它没有)。
      • @Pharap: 1) 仍然需要一个独立的实现来提供标准库的某个子集,例如std::size_t。 2) 抛出的替代方法是终止,或调用适合您的用例的任何非返回处理程序。
      • @KerrekSB Arduino 提供size_t,但不提供std::size_t。尽管使用了 C++11 编译器,Arduino 并没有实现任何 C++ 标准库,它只实现了 C 标准库的一些方面和它自己的一些扩展。异常处理是可用的,但不鼓励,也没有 stdlib 异常类。也就是说,这个答案票数很少的原因是因为它是一个通用的答案,没有考虑到 Arduino 的特质。
      猜你喜欢
      • 1970-01-01
      • 2011-10-10
      • 1970-01-01
      • 2022-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多