Arduino预定义数组内存占用异常:数组大小不影响程序内存占用
嘿,这个问题我之前调试代码时也碰到过类似的,给你几个接地气的排查方向:
检查数组是否被编译器优化移除
Arduino用的avr-gcc编译器默认会开启优化,如果你定义的数组完全没有被读写操作(比如只是声明了但没用到),编译器会直接把它从最终的二进制文件里删掉。这时候不管你调整数组大小甚至移除它,生成的文件大小都不会变。
测试方法:给数组加个简单的使用场景,比如Serial.println(myArray[0]);,哪怕只是读一个元素也行,然后重新编译看看大小有没有变化。如果确实是优化的问题,要是想强制保留数组(仅测试用),可以用volatile修饰:volatile int myArray[50];,不过实际代码里别随便加volatile,会影响性能。确认数组存储的区域是SRAM还是Flash
如果你用了PROGMEM宏定义数组(比如const char myLookupTable[] PROGMEM = {"abcdef"};),这个数组会被存在Flash(程序存储区)里,而你可能只盯着SRAM的占用看。编译完成后,看IDE底部的输出:Sketch uses ... bytes (X%) of program storage space. Maximum is ... bytes.
Global variables use ... bytes (Y%) of dynamic memory.
第一行是Flash的占用,第二行是SRAM。如果数组在Flash,调整大小只会影响第一行的数值,SRAM占用自然不变。排查编译缓存或IDE的编译机制
有时候Arduino IDE会偷懒用之前的编译缓存,哪怕你改了代码也没重新编译整个工程。可以打开IDE的文件->首选项,勾选显示 verbose 输出里的编译选项,重新编译时看输出日志,确认是不是真的重新编译了所有相关文件。要是怀疑缓存问题,直接手动删除临时编译文件夹:- Windows:
%LOCALAPPDATA%\Arduino15\build - Mac:
~/Library/Arduino15/build - Linux:
~/.arduino15/build
- Windows:
检查数组的作用域和使用场景
如果数组是局部变量(比如在某个函数内部定义),而且这个函数从来没被调用,或者数组在函数里没被实际使用,编译器同样会把它优化掉。可以把数组改成全局变量试试,或者确保函数被执行到,数组有读写操作。测试极端大小的数组变化
要是你只是微调数组大小(比如从10个元素改成20个),可能因为链接器的内存对齐策略,文件大小的变化被填充字节抵消了。试试把数组改得特别大,比如从10个int改成1000个int,重新编译后看程序存储区的占用,要是这时候有明显变化,那之前的小调整就是对齐导致的无变化。
内容的提问来源于stack exchange,提问作者eJm

