没有操作系统的运行时内存分配

问题描述 投票:0回答:2

最近,我一直在考虑如何完成编译时内存分配。据我所知,编译器在编译时为变量分配固定数量的字节。这对于这样的语句是有意义的:

char buffer[256];

编译器将为变量分配256字节的内存,这将是它的结束。如果我想动态创建内存,我需要使用OS提供的malloc等函数。然后我想到了这个函数,它不会使用任何操作系统相关的功能,但它会像动态分配一样。

*char malloc(size_t size) {
    char (*mem)[size];
    return mem;
}

编译器无法预先分配内存,因为在程序运行时可以多次调用此函数。这究竟是如何工作的?编译器如何处理这样的函数?我会假设操作系统处理此问题,但这并不使用任何操作系统相关的功能,这意味着它可以在没有操作系统的硬件上运行。

c memory memory-management
2个回答
1
投票

首先,*char应该是char*mem不应该是指针::

char* malloc(size_t size) {
    char mem[size];
    return mem;
}

这会将size字节的内存分配为堆栈上的局部变量。如您所知,函数退出时会破坏局部变量。它返回一个指向局部变量的指针,然后由于函数退出局部变量而被销毁。实际上,该空间将被重用于下一个函数调用的局部变量。

如果您尝试以这种方式分配两块内存,您将获得相同的地址:

char *mem1 = malloc(10); // using your malloc
char *mem2 = malloc(10); // using your malloc
// probably mem1 and mem2 point to the same memory now

如果调用另一个函数,内存可能会被破坏,因为该函数也允许使用局部变量:

char *mem1 = malloc(10); // using your malloc
strcpy(mem1, "abcde"); // if you're lucky, strcpy won't crash...
printf("Hello world.\n");
printf("mem1 contains %s\n"); // it won't be abcde because strcpy or printf overwrote the memory

简而言之:

这究竟是如何工作的?

它不会。


-1
投票

缩小术语操作系统 - 当你说操作系统时,你实际上是指像Windows或Unix这样的“桌面操作系统”,它不仅可以处理多任务处理,还可以处理内存分配,文件系统,驱动程序等等。但也有RTOS除了处理多任务之外什么都不做 - 他们不关心动态内存分配。

不使用“桌面操作系统”的应用程序,例如微控制器应用程序,但出于某些混淆的原因,无论如何都想使用malloc,在链接时为堆预留一定量的RAM。 malloc然后统治这个记忆区域,并从那里取得内存。在这种情况下,malloc仅由编译器库实现和处理。

这说明了使用malloc进行此类应用是多么无意义。首先,嵌入式系统不运行多个程序,并且它们永远不会停止执行程序,因此它对free()内存永远不会有意义 - 你是谁解放它的?没有其他程序可以共享RAM。您的程序可以独占访问所有可用的RAM内存。

所以你在RAM中有这个固定区域标记为堆并禁止用于除malloc以外的任何人,你可以在那里存储静态分配的变量。这实际上是浪费空间。因为无论如何,您的程序必须能够处理RAM峰值使用峰值的最坏情况。此时,无论是静态存储,还是堆栈或堆上,都必须有一定数量的可用内存。

这意味着任何这样的程序必须提前预留那些确切的内存,否则它将会中断 - 它将需要与最坏情况一样多的RAM。既然你必须支持这种最坏的情况,你就不能以任何明智的方式将这些记忆重新用于其他目的。

至于存储临时变量,已经存在堆栈,这更快,更安全。所以你不需要malloc

这是在没有操作系统的系统中从未使用堆分配的主要原因 - 它没有意义。我一直看到混乱的PC程序员启动嵌入式系统编程,在你知道它之前,他们开始使用malloc,因为他们“不知道在编译时需要多少内存”。但是在嵌入式系统上,你必须始终知道这一点 - 你需要足够的时间来处理最坏的情况。因此,您需要为所有内容设置固定的最大限制。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.