c - C 中的大数组初始化问题

标签 c arrays image initialization msp430

需要您帮助解决三个问题(我猜这或多或少涉及同一主题)。

1)我有一个大型 int 数组,它是通过以下方式初始化的:

int arr [] = {.....}; // allot of values !!

在程序中,只有一个函数“使用”该数组进行“只读”操作。 关于这个数组我们有两个选择:

a) 在 that 函数中将该数组声明为本地数组。

b) 将其声明为该函数外部的全局数组。

对于这两种情况,程序的镜像文件将如何修改?

如何修改程序的执行速度?

2) 关于TI MSP430微 Controller :

我的程序中有一个非常大的 C 风格字符串全局数组,如下所示:

char *arr [] = {"string 1","string2",.......}; // allot of strings

通常,在主程序开始时,我使用命令来停止“看门狗”计时器。 在我看来,例如,在需要初始化一个非常大的数组的情况下,它是需要的......所以我的问题是:

是这样吗? (有大量的“字符串”)?数组什么时候初始化?

如果我以不同的方式声明它会重要吗?

3) 在 C++ 中,问题 1 和 2 的答案(如果是这样)有何不同?

谢谢分配, 盖伊。

最佳答案

“对于每种情况如何修改程序的图像文件?”:

  1. 如果将其声明为局部变量,则可执行文件的总大小将保持不变,但每次调用该函数时,都会在其余部分之前进行大量数据复制操作。函数代码被执行。

  2. 如果将其声明为全局变量,则可执行文件的总大小将会增加,但在运行时不会有额外的数据复制操作,因为图像值将被硬编码到可执行文件中本身(如果有什么区别的话,可执行文件的加载时间将会增加)。

因此,选项 #1 在大小方面更好,而选项 #2 在性能方面更好。

但是,请注意,在第一个选项中,您很可能在运行时出现堆栈溢出,这将导致您的程序执行内存访问冲突并崩溃。为了避免这种情况,您必须增加堆栈的大小,通常在项目的链接器命令文件 (*.lcf) 中定义。增加堆栈的大小意味着增加可执行文件的大小,因此选项 #1 在任何方面都不比选项 #2 好,让您只有一个选择(将其声明为全局变量)。

另一个问题是,您可能想将此数组声明为 const,原因有两个:

  1. 如果您尝试更改此只读数组中的值,它将防止运行时错误(并提供编译错误)。

  2. 它将告诉链接器在程序的 RO 部分分配该数组,该数组可能映射到 MSP430 上的 EPROM。如果您选择使用const,那么链接器将在程序的RW部分分配该数组,该部分可能映射到RAM。因此,这个考虑实际上是一个问题 - 您的内存不足,RAM 还是 EPROM。如果您不确定,可以在项目的链接器命令文件中或在每次构建项目时生成的映射文件中检查它。

“全局数组什么时候初始化?”:

它在编译期间初始化,实际值被硬编码到可执行文件中。

因此,这里不涉及运行时,并且还有其他原因导致您的看门狗执行硬件重置(我的猜测 - 某些内存访问冲突导致您的程序崩溃)。

注意:

可执行程序通常分为三个部分:

  • 代码(只读)部分,包含代码和所有常量变量。

  • 数据(读写)部分,包含所有非常量全局/静态变量。

  • 堆栈(读写)部分,所有其他变量在运行时分配。

每个节的大小和基地址可以在项目的链接器设置(或项目的链接器命令文件)中配置。

关于c - C 中的大数组初始化问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21314321/

相关文章:

c++ - 嵌入式日志记录

c++ - IUnknown 中的 addref 和 release,它们实际上是做什么的?

arrays - 如何在只有某些条件需要为 TRUE 的数组公式中包含 OR - Excel 第 2 部分

javascript - : Calling array. prototype.push 一次包含所有元素或推送每个元素一次哪个性能更高?

ruby-on-rails - 性能:遍历一个数组,除了一个元素

javascript - 正则表达式匹配字符串,如果不匹配

c - 如何在 C 字符串中嵌入双引号?

c - 从基带 (ffmpeg) 编码帧时 avcodec_encode_video2 出现段错误

image - 如何使用matlab使用对象的边界框裁剪图像中检测到的对象

java - 在 Android 中叠加图像