我知道有关此主题的问题很多,但我的问题特别是:如果我分配内存来表示一个缓冲区,然后再也不会在代码中分配内存,会发生什么情况。然后我需要释放该内存吗?
我的代码应用将用于嵌入式设计,因此是微控制器。代码看起来像这样:
action
为缓冲区分配内存发生在#include "ringbuffer.h"
const int BUFFER_SIZE = 5;
// create instance of ring buffer
ringbuffer buff1;
ringbuffer buff2;
int main(void)
{
// initialize ring buffer (this allocates memory to buffers)
ringbuffer_init(BUFFER_SIZE, &buff1);
ringbuffer_init(BUFFER_SIZE, &buff2);
while(true)
{
// receive data in buffer here
// do stuff with data
// run forever
}
// memory is never freed for the buffers
return 0;
}
函数内部,并且该函数只能在main的开头,循环之前运行一次。
我的问题是真的。如果我将内存分配给缓冲区,再也不要释放它,而我又关闭再打开微控制器,它会分配内存两次,以便随着时间的推移它堆积并崩溃吗?
GitHub上的.c和.h环形缓冲区库文件。
答案 0 :(得分:3)
如果我分配内存来表示一个缓冲区,然后再也不会在代码中分配内存,那会发生什么。然后我需要释放该内存吗?
在托管的类似PC的系统上,使用完后需要释放内存。操作系统将回收它,但您仍应释放它。部分原因是清理自己的混乱的好习惯,部分原因是这样做时,程序中所有与堆相关的错误都将在早期浮出水面。当您在调用free()
时导致程序崩溃时,实际的错误在程序中的其他位置。
在独立式(微控制器/ RTOS)系统上,您不应该首先使用动态分配,因为it doesn't make any sense。如果出于未知原因您仍然坚持使用它,则不需要free()它,因为您的程序控制了计算机中100%的可用资源。
我对代码的应用将用于嵌入式设计,因此是微控制器。
您不应在嵌入式系统中使用该Github项目。您需要摆脱malloc并将其替换为静态分配的缓冲区,每个环形缓冲区实例一个。
答案 1 :(得分:2)
如果我将此内存分配给缓冲区,再也不要释放它,而我又关闭并打开我的微控制器,它将分配两次内存,以便随着时间的推移它会堆积并崩溃?
否,结束程序时,操作系统通常会回收内存。
在您的情况下,您具有嵌入式系统,并且不结束程序。通常会发生的情况是,当您重新启动系统时,启动代码将再次分配内存区域,并且您只会分配一次内存。虽然不能保证每次都分配相同的地址。
话虽这么说,这是一个好习惯,free
处理完内存后就可以了。这是因为随着程序的变大和编写可用于其他系统的代码,在程序部分的末尾free
变得很重要。
答案 2 :(得分:1)
嵌入式微控制器的一般规则是永远不要使用动态内存分配,因为在微控制器可用的有限内存空间中,随着时间的流逝,您会获得内存空间碎片,并最终出现在内存管理器找不到内存的情况下。足够大的可用内存块来完成内存分配。
我可以想到两种情况可以允许在堆外分配内存
在第一种情况下,任何分配失败都将在主代码启动之前发生,并且长时间运行后也不会发生分配失败,因为再也没有分配尝试了。
在第二种情况下,假设可用内存可以支持最大数量的分配,则内存不会变得零散,因为任何新分配将始终适合已释放的块。
在这种情况下,只要有电源,应用程序就可以继续运行,而不必释放内存。断开电源后,内存将不可避免地释放。
答案 3 :(得分:0)
如果关闭电源并重新启动控制器,则所有内存都将丢失。启动代码应将整个内存初始化为0,并且操作系统应能够再次为缓冲区分配相同的内存。
如果通常在嵌入式系统上使用malloc是一个好主意,则主要取决于所使用的操作系统。大多数嵌入式OS使用可定义数量的不同固定大小的内存块,并根据需要根据请求的大小分配它们。它们主要支持某种统计信息,因此您可以观看这些块的使用。
不要在函数中创建大型缓冲区作为自动变量。他们可以炸开烟囱。请注意,对于init部分,将静态var声明为缓冲区也可能会占用FLASH / ROM内存。 (静态变量默认情况下已初始化。)