代码之家  ›  专栏  ›  技术社区  ›  Martin

我怎么知道我的记忆何时已满?

  •  3
  • Martin  · 技术社区  · 14 年前

    我正在用c语言为Atmel XMEGA微控制器编写固件,我想我已经填满了4kb的SRAM。据我所知,我只有静态/全局数据和本地堆栈变量(I 在我的代码中使用malloc)。

    我使用一个局部变量来缓冲一些像素数据。如果我把缓冲区增加到51字节,我的显示器就会显示奇怪的结果——6字节的缓冲区就可以了。这就是为什么我认为我的内存已满,堆栈正在覆盖某些内容。

    当内存被填满而不是让它覆盖其他一些数据时,是否有可能退出(例如通过重置微控制器)?

    4 回复  |  直到 14 年前
        1
  •  3
  •   Will Dean    14 年前

    很难准确地预测您需要多少堆栈(如果您选择了正确的选项,一些工具链可能会尝试这样做,但这只是一个粗略的指南)。

    检查堆栈状态的一种常见方法是在启动时用已知值将其完全填充,尽可能长/硬地运行代码,然后查看有多少未被覆盖。

    不幸的是,虽然这些概念非常简单:用一个已知的值填充堆栈,计算剩余的值的数量,但是实现它的现实需要对特定工具(特别是启动代码和链接器)的工作方式有相当深入的了解。

    检查堆栈溢出是否是导致问题的原因的简单方法是使所有本地数组“静态”和/或大幅增加堆栈的大小,然后查看是否工作得更好。在小型嵌入式系统上,这两者都很难做到。

        2
  •  1
  •   Curd Erin Yueh    14 年前

    “是否有可能(例如。 通过重置微控制器)当 让它覆盖其他一些数据?”

    我想你现在有一个类似(1)的内存映射。 当堆栈和/或变量空间增大到很大时,它们会相互碰撞并覆盖(*)。

    当堆栈或变量空间超过最大空间时,它们命中未映射的ADDR空间(*)。 取决于控制器(我不确定AVR系列),这会导致重置/陷阱或类似的(=你想要的)。

      [not mapped addr space][   RAM  mapped  addr  space   ][not mapped addr space] 
    (1)                      [variables --->  *   <--- stack] 
    (2)                     *[ <--- stack   variables --->  ]* 
    

    (如果使用更多变量/堆栈,箭头指示增长方向)

    当然,最好事先确保RAM足够大。

        3
  •  1
  •   Roddy    14 年前

    还要注意,如果处理的是多线程应用程序,那么每个线程都有自己的堆栈,这些堆栈经常在线程启动时从堆中分配。

    除非处理器上有一些硬件检查堆栈溢出(不太可能),否则可以使用一些技巧来监视堆栈使用情况。

    • 用一个已知的标记模式填充堆栈,并检查堆栈内存(由链接器分配)以确定有多少标记保持未损坏。
    • 在计时器中断(或类似中断)中,将主线程堆栈指针与堆栈基部进行比较,以检查是否溢出

        4
  •  0
  •   ruslik    14 年前

    通常,您的编程工具知道控制器的参数,因此如果您使用更多(没有mallocs,它在编译时是已知的),则应该警告您。

    但是你应该注意像素数据,因为大多数显示器没有线性地址空间。