2

私は(具体的にはArduino の C++ 標準ライブラリへの回答、およびスタック オーバーフローの質問C++ 文字列と Arduino 文字列。それらを組み合わせる方法は?new ))、Arduino コンパイラは演算子を実装していないと言われました。しかし、それを使用する 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.

それで、なぜ私はこれを聞き続けるのですか?これらの人々は間違っているのでしょうか、それとも単に私が彼らの意味を誤解しているだけなのでしょうか?

4

3 に答える 3

14

newArduinoディストリビューションdeleteの一部として定義されています: /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います。

于 2013-04-29T09:04:59.363 に答える
9

あなたが示したように、原則としてArduinoで動作しnewますdelete 問題は、Arduino には、グローバル変数、スタック、およびヒープを組み合わせた2K の RAM があるため、Arduino用に作成する実質的なプログラムは、メモリ使用量を十分に認識している必要があることです。

したがって、このような組み込みシステムでは、一般に、汎用の動的割り当てよりも静的割り当て (場合によってはクラスごとの動的割り当て) を使用することをお勧めします。単純なプログラムの場合、動的割り当ては必要ありません。複雑なプログラム、あなたはそれを買う余裕はありません。

于 2013-04-29T14:55:32.793 に答える
1

プラットフォームが事前に定義されていないからといって、それを定義でき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
{
}

これは明らかに非常に速くメモリ不足になります。

于 2013-04-29T08:42:07.043 に答える