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%!

现在有一些关于是否使用newmalloc() 的讨论,但我没有发现草图大小大幅增加的暗示。

所以,如果有人想解释这一巨大增长的来源,那就太好了! 此外,如果有人知道类似的陷阱,很高兴与您分享 ;)

这是一个演示代码,你自己检查一下:

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 草图的大小 - 为啥?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Bouncy Castle 库会导致输出 .jar 文件大小大幅增加

响应时间从 100 到 150 个用户负载测试大幅增加

Xcode弃用Bitcode,导致应用体积大幅增加

为啥生成 pdb 文件会导致静态链接库的大小大幅增加?

声明抽象类(纯虚方法)大幅增加二进制大小

2021最新互联网公司校招名额大幅增加