【发布时间】:2020-03-16 17:39:39
【问题描述】:
有没有办法检测数组(或任何变量)何时会大于系统中的可用内存量?其次,如果声明了这样一个变量,会发生什么?
一些背景知识:我使用的是具有 20KB RAM 的嵌入式 ARM 设备;它没有运行 RTOS。我正在尝试将传感器数据读取到数组中,但是可以读取大量传感器数据。如果我使用 malloc 分配内存,我可以检查 return != NULL 以查看堆上是否有足够的空间可用(尽管this question 似乎表明这可能是乐观的)。但是,我不确定当声明一个大于可用内存的数组时会发生什么。
显而易见的解决方案是按照链接问题的已接受答案所述执行操作:预先为数据分配所有内存。但是如果动态声明数组,如何判断系统是否内存不足,如果没有会发生什么?
编辑:一些示例,以说明我所指的内容。 如果像这样定义一个数组会发生什么:
void breaking_things(){
uin8_t contrived_example[30000] = {0};
}
这在我只有 20KB 可用空间的系统上是不可能的,但是会发生什么。
再举一个例子:
void breaking_things(){
uin8_t contrived_example0[7000] = {0};
uin8_t contrived_example1[7000] = {0};
uin8_t contrived_example2[7000] = {0};
}
【问题讨论】:
-
你能解释一下你是如何分配数组的吗?数组是分配有
malloc(似乎不是这种情况),分配为静态内存还是分配为堆栈内存,这会有所不同。一个简单的代码示例可能会有所帮助。 -
在小型嵌入式系统中使用动态分配通常是一种不好的形式。计算出设备中有多少内存,将其全部分配给一个大的静态数组,然后从中取出你需要的东西(可能使用简单的标记释放分配器之类的东西)。
-
如果您将数组定义为全局数组,那么链接器会告诉您您的 BSS 部分与其他部分重叠。当然,假设一个正确的链接器脚本......如果它是本地的(在堆栈上)那么......那么这是一个坏主意。
-
正如我所说,最实用的方法是定义一个静态(全局)数组,让链接器担心空间。您的示例溢出了堆栈,这几乎无法检测到(直到为时已晚)。
-
在我看来,这条路充满了危险。有不同的方法可以检查剩余堆栈大小,但它们要么依赖于平台,要么非常脆弱。我个人不会去那里。但例如:Is it possible to predict a stack overflow in C on Linux?