c++ - 如果我提前将参数声明为变量而不是将它们写入函数调用的行内,它有什么区别(在内存方面)?
问题描述
例如,对于 dummy function write(int length, const char* text){...}
,这两种方法在内存方面有什么区别吗?
write(18,"The cake is a lie.");
或者
int len = 18;
char txt[19] = "The cake is a lie.";
write(len,txt)
奖励:如果有一些重复怎么办?即循环使用一个数组重复调用该函数,该数组的元素是预期的参数。
我问这个问题,特别是奖金,希望更好地了解每个人如何消耗内存以优化我在 Arduino 等内存敏感平台上编写时的效率。也就是说,如果您知道更有效的方法,请分享!谢谢!
解决方案
这取决于是在函数范围内char txt[19]
声明还是在全局(或命名空间)范围内声明。
如果在函数范围内,则将在堆栈上分配并在运行时从驻留在(只读)数据段中的字符串文字txt
的副本初始化。
如果在全局范围内,那么它将在构建时在数据段中分配。
奖励:如果它被分配在某个子范围内,比如循环体,那么你应该假设它会在每次循环迭代期间被初始化(优化器可能会做一些技巧,但不要指望它)。
示例 1:
int len = 18;
char txt[19] = "The cake is a lie.";
int main() {
write(len,txt);
}
这里len
(an int
) 和txt
(19 字节 + 对齐填充) 将在构建时分配到程序的数据段中。
示例 2:
int main() {
int len = 18;
char txt[19] = "The cake is a lie.";
write(len,txt);
}
在这里,字符串文字"The cake is a lie."
将在构建时分配到程序的数据段中。此外,len
和txt
(19 字节 + 填充)可能会在运行时在堆栈上分配。优化器可能会忽略len
分配,甚至可能会忽略txt
,但不要指望它,因为它取决于许多因素,例如write
body 是否可用、它到底做了什么、优化器的质量等。如果有疑问,查看生成的代码(godbolt现在支持 AVR 目标)。
示例 3:
int main() {
write(18,"The cake is a lie.");
}
在这里,字符串文字"The cake is a lie."
将在构建时分配到程序的数据段中。将18
嵌入程序代码中。
由于您在 AVR 上进行开发,因此还有一些额外的细节值得一提,即应用程序的可执行文件最初存储在Flash中,一旦您“运行”它,它就会被复制到 RAM 中。可以避免复制到 RAM 并使用PROGMEM
关键字将数据保留在 Flash 中(尽管要对数据做任何有意义的事情,您需要将其复制到 RAM 中)。
推荐阅读
- d3.js - d3数据绑定不使用连接创建子元素
- r - 使用 R 将气泡数据强加到图像上
- mysql - 从 nodejs GKE pod 连接到外部 mysql 数据库
- wolfram-mathematica - 在 Mathematica 中显示元胞自动机规则图标的图形
- database - 问题:添加关注/关注者功能时最好的数据库结构是什么?
- python - 以系统的方式更改字符串以避免重复?
- android - 获取 Gallery Image Android Xamarin 的路径并在 System.Drawing.Bitmap("path") 中使用它?
- c - 检测 C 库
- azure-active-directory - 如何配置 MSAL 以支持 AAD、Angular 7+、Azure Funcs
- c++ - std::string 源代码中宏的使用