C中的大数组初始化问题

时间:2014-01-23 16:46:03

标签: c arrays image initialization msp430

在三个问题中需要你的帮助(我猜这个问题或多或少都与我相同)。

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

int arr [] = {.....}; // allot of values !!
程序中只有一个函数“使用”该数组进行“只读”操作。 关于这个数组我们有两个选择:

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

b)将其声明为此函数之外的全局数组。

如何针对这两种情况修改程序的图像文件?

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

2)关于TI MSP430微控制器:

我的程序中有一个非常大的C样式字符串数组,如下所示:

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

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

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

如果我以不同的方式声明它会有关系吗?

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

谢谢分配, 盖

2 个答案:

答案 0 :(得分:2)

你有第三种选择;在函数中声明它,但使用static关键字:

void func()
{
  static int arr[] = {...};
  ...
 }

这将在不同的内存段中留出存储空间(取决于体系结构和可执行文件格式;对于ELF,它将使用.data段),它将在程序启动时初始化并保持到程序终止。

优点:

  • 在程序启动时,而不是每次进入函数时,都会分配和初始化数组;
  • 数组名称仍然是函数的本地名称,因此程序的其余部分不可见;
  • 数组大小可能比在堆栈上分配的数据大得多;

缺点:

  • 如果数组不是真正的只读,但是由函数更新,则该函数不再可重入;

请注意,如果数组真正意味着只读,您可能需要声明它

static const int arr[] = {...}

答案 1 :(得分:2)

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

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

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

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

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

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

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

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

    3. “全局数组何时初始化?”:

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

      所以这里没有涉及运行时间,并且还有其他东西导致你的看门狗执行硬件重置(我的猜测 - 一些内存访问违规会导致你的程序崩溃)。

      注意:

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

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

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

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

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