2013-04-29 59 views
2

有人告訴我,(特別是在an answer to C++ Standard Library on Arduino,並在堆棧溢出問題C++ string and Arduino String. How to combine them?))的Arduino的編譯器沒有實現new操作。不過,我已經爲Arduino(在Arduino IDE中)編寫了一個使用它的程序,它完美地工作。運營商新的Arduino的

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. 

那麼,爲什麼我不斷聽到這個?這些人是錯的,還是我誤解了他們的意思?

+2

正如他們在軍隊中所說的,如果地圖與地形不匹配,請相信地形。 – 2013-04-29 12:25:27

回答

10

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,請擁有它們。

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 
{ 
} 

這顯然會非常快地耗盡內存。

+0

但我沒有定義它。而且我沒有使用任何特殊的庫。因此,如果所有形式的'operator new'都具有定義,那麼與Arduino平臺上的'new'是否「實現」不同?當他們說Arduino不支持'new'或'delete'時,這些人是什麼意思?顯然他們工作,那麼問題是什麼? – anthropomorphic 2013-04-29 08:53:26

+0

我喜歡這被稱爲「寶貝的例子。「 – 2016-05-29 06:04:23

+0

這個例子有兩個問題:1:試圖在嵌入式系統上使用異常,2:假設Arduino有一個'std'命名空間(它不會) – Pharap 2017-08-20 07:23:28

9

正如你已經證明,newdelete做Arduino的原則工作。問題是你的Arduino有2K的RAM用於全局變量,堆棧和堆合併,所以你爲它編寫的任何實質程序都必須高度關注內存使用情況。

因此,對於像這樣的嵌入式系統,通常最好使用靜態分配(或者在某些情況下可能是按類動態分配),而不是通用動態分配:對於簡單的程序,您不需要需要動態分配,對於複雜的程序,你不能負擔得起它。