【问题标题】:Local variable and static variables局部变量和静态变量
【发布时间】:2014-08-14 14:34:04
【问题描述】:

我只是想了解RAM分配的区别。

为什么如果我在函数之前定义一个变量会导致 RAM 溢出,而当我在函数中定义它时就可以了?

例如:

/*RAM OK*/
void Record(int16_t* current, int i,int n)
{
  float Arr[NLOG2] = {0};
  for(i=0;i<n;i++)
      Arr[i]=current[i*5];
}

/*RAM OVERFLOW*/
static float Arr[NLOG2] = {0};

void Record(int16_t* current, int i,int n)
{
   for(i=0;i<n;i++)
       Arr[i]=current[i*5];
}

这是消息:

无法为总估计数的部分/块分配空间 0x330b 字节的最小大小(最大对齐 0x8)在 (总未提交空间0x2f38)。

【问题讨论】:

  • 是否显示消息 RAM 溢出?
  • n 声明在哪里?
  • 这是消息:无法为 (总未提交空间 0x2f38)中总估计最小大小为 0x330b 字节(最大对齐 0x8)的部分/块分配空间。

标签: c variables static ram


【解决方案1】:

不同的是,第一种情况,Arr是在栈上声明的;在调用该函数之前,该数组不存在。生成的二进制文件包含用于创建数组的代码,但数组本身不在二进制文件中。

然而,在第二种情况下,Arr 被声明在任何函数之外(也就是在文件范围内)。因此,它始终存在,并以二进制形式存储。因为您似乎是在嵌入式平台上工作,所以这个原本微不足道的差异会导致您的“RAM 溢出”错误。

【讨论】:

  • 但是当我调用它们时,这两个函数会产生相同的结果?可以使用第一种情况而不是第二种情况吗?
  • @user3428151 只有第一种情况会创建数组。至于哪种方法可以,取决于你想用Arr做什么。第一种情况,只要函数返回,Arr 就不再存在了。
  • 谢谢,这个数组只被这个函数使用,所以我可以创建一个本地定义。
【解决方案2】:

在第二种情况下,数组是在应用程序启动时分配的。它会一直保留在内存中,直到应用退出。

在第一种情况下,仅在调用函数void Record(int16_t* current, int i,int n) 时才分配数组。函数执行完毕后数组就消失了。

如果您只有一个编译单元(.o 文件),static 关键字不会产生任何影响。

全局变量(不是static)在您创建链接器可用于其他文件的.o 文件时就在那里。因此,如果您有两个这样的文件,您会在a 上遇到名称冲突:

交流:

#include <stdio.h>

int a;

int compute(void);

int main()
{
    a = 1;
    printf("%d %d\n", a, compute());
    return 0;
}

b.c:

int a;

int compute(void)
{
    a = 0;
    return a;
}

因为链接器不知道要使用哪个全局as。

但是,当您定义静态全局变量时,您是在告诉编译器仅为该文件保留变量,不要让链接器知道它。因此,如果您将static(在a 的定义中)添加到我编写的两个示例代码中,您将不会发生名称冲突,因为链接器甚至不知道其中任何一个都有a文件:

交流:

#include <stdio.h>

static int a;

int compute(void);

int main()
{
    a = 1;
    printf("%d %d\n", a, compute());
    return 0;
}

b.c:

static int a;

int compute(void)
{
    a = 0;
    return a;
}

这意味着每个文件都使用自己的a,而不知道其他文件。

【讨论】:

    猜你喜欢
    • 2018-04-18
    • 1970-01-01
    • 1970-01-01
    • 2015-10-04
    • 1970-01-01
    • 2018-08-02
    • 1970-01-01
    • 2016-07-26
    • 1970-01-01
    相关资源
    最近更新 更多