new-Operator 大幅增加了 Arduino 草图的大小 - 为啥?
Posted
技术标签:
【中文标题】new-Operator 大幅增加了 Arduino 草图的大小 - 为啥?【英文标题】:new-Operator increases Arduino sketch size drastically - why?new-Operator 大幅增加了 Arduino 草图的大小 - 为什么? 【发布时间】:2015-02-22 04:21:55 【问题描述】:在将我的部分代码重构为一个类时,我选择将一个静态大小的数组更改为一个动态数组,我对我的草图大小感到震惊,增加了约 579%!
现在有一些关于是否使用new
或malloc()
的讨论,但我没有发现草图大小大幅增加的暗示。
这是一个演示代码,你自己检查一下:
void setup()
// put your setup code here, to run once:
#define BUFLEN 8 * sizeof(char)
#define BUFVAL '5'
#define BUFARR BUFVAL,BUFVAL,BUFVAL,BUFVAL,BUFVAL,BUFVAL,BUFVAL,BUFVAL,0
#define MODE 2
int i = 0;
Serial.begin(115200);
#if (MODE == 0)
//10.772 Bytes for an Arduino Due on IDE 1.57 -> 2% of total
char empty_page[BUFLEN+1] = BUFARR;
#elif (MODE == 1)
//12.772 Bytes for an Arduino Due on IDE 1.57 -> 2% of total, ~18.5% increase
char *empty_page = (char *)malloc(BUFLEN+1);
memset(empty_page, BUFVAL, BUFLEN);
empty_page[BUFLEN+1] = '\0'; // NULL Terminate
#elif (MODE == 2)
//73.152 Bytes for an Arduino Due on IDE 1.57 -> 13% of total, ~579% increase
char *empty_page = new char[BUFLEN+1]BUFARR;
#endif
Serial.println("Result: ");
for(i=0; i<BUFLEN; i++)
Serial.print(empty_page[i]);
Serial.println("");
#if (MODE == 1)
free(empty_page);
#elif (MODE == 2)
delete[] empty_page;
#endif
void loop()
// put your main code here, to run repeatedly:
要在没有 arduino 的情况下检查此代码:http://ideone.com/e.js/bMVi0d
编辑:
我的理解是,new
引导 IDE 编译一些大型 c++ 内容以处理它。另一方面,IDE 的详细编译器输出是相同的。
我正在尝试最小化我的草图,其他任何有此目标的人肯定也会对像“新”这样的部分感兴趣,你需要避免这些部分以获得更小的草图。这似乎是一个通用的 Arduino IDE 东西,所以应该有更多的元解释。
【问题讨论】:
让你的链接器生成一个地图文件——你会立即看到是什么占用了所有的空间。 @CarlNorum 你能详细说明一下吗? IDE 的详细输出对于 MODE 0 和 MODE 2 是相同的。建议使用“avr-size”或“avr-objdump”来访问此映射文件涉及在 Windows 上设置 cygwin,这是另一个盒子蠕虫,老实说,我不知道这会有什么帮助。 【参考方案1】:new 运算符本质上是 malloc 的类型安全版本,旨在减少 C++ 中的错误。您可以从代码here 中看到,new 实际上只是调用 malloc 并添加了一些花里胡哨。至于何时使用 new 与 malloc,可以在 here 找到一个很好的讨论,其中主要结论是几乎所有 C++ 程序都应该使用 new。话虽如此,您不需要额外的花里胡哨来制作 char 数组,因为您不需要为原始类型调用构造函数(调用构造函数是 new 运算符的主要功能之一。另外值得注意的是,原始类型根本没有构造函数,因此编译器可能会失去搜索构造函数的性能)。如果内存非常重要,那么 malloc 是一个完全可以接受的解决方案。您的 malloc 代码看起来非常好,应该更适合您的目的。
【讨论】:
在 Arduino 的情况下,它似乎不仅仅是几个铃铛,它增加了超过 60kB 到二进制草图大小 - 我想知道为什么以及为什么 malloc 版本使用这么少如果基本上是一样的。【参考方案2】:您混淆了几个部分。 “IDE”是集成开发环境。这是一个 GUI,它充当一些工具的集成前端,包括编译器和链接器。这个问题看起来像一个链接器问题。
特别是,这看起来像是一个非常糟糕的编译器。它会拖入大约 60 kB,而应该拖入 nothing。类型安全应由编译器处理。这里编译器应该告诉编译器只使用malloc
而不是new[]
,因为所有类型检查都通过了。
您应该明白,Arduino 是一种廉价产品,而且工具并不是最先进的。
【讨论】:
Arduino IDE 使用 gcc 编译器,顺便说一下,Arduino IDE 并不比 gcc 便宜(它们都是免费的)。虽然 Arduino IDE 不是超级先进,但它生成的二进制文件与使用 gcc 的其他任何东西相同。 @rasmus:我说 Arduino 本身很便宜。后果包括 Gcc 中的 Arduino 后端缺乏资金。以上是关于new-Operator 大幅增加了 Arduino 草图的大小 - 为啥?的主要内容,如果未能解决你的问题,请参考以下文章