7

我正在研究这个 malloc 函数,我可以使用一些帮助:

static void *malloc(int size)
  {
        void *p;

        if (size < 0)
                 error("Malloc error");
        if (!malloc_ptr)
                 malloc_ptr = free_mem_ptr;

        malloc_ptr = (malloc_ptr + 3) & ~3;     /* Align */

        p = (void *)malloc_ptr;
        malloc_ptr += size;

        if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr)
                 error("Out of memory");

        malloc_count++;
        return p;
 }

我知道 malloc 函数为任何类型分配内存空间,如果有足够的内存,但我不明白的行是:

p = (void *)malloc_ptr;
malloc_ptr += size;

它怎么能指向任何这样的数据类型呢?我只是无法理解那个 void 指针或其位置。

注意: malloc_ptr 是一个无符号长整数

4

5 回答 5

7

它返回 void 指针的原因是因为它不知道您在malloc调用中为什么分配空间。它只知道您请求的空间量。由您或您的编译器决定填充内存的内容。void 指针的位置通常被实现为一个链表,以保持完整性并知道哪些内存值是空闲的,这令人惊讶地在free函数中跟踪。

于 2012-12-25T19:28:00.613 回答
3

这是 的实现malloc因此允许执行常规程序中不合法的事情。具体来说,它利用了实现定义的从unsigned longto的转换void *。程序初始化设置为一大块未分配内存malloc_ptr数字地址。然后,当您请求分配时,malloc从 的当前值中生成一个指针,malloc_ptr并增加malloc_ptr您请求的字节数。这样,下次您调用malloc它时将返回一个新指针。

这是关于malloc. 最值得注意的是,它似乎从未重用释放的内存。

于 2012-12-25T19:31:25.677 回答
2

Malloc 正在为一块完全非结构化的平面内存返回一个指针。(void *) 指针意味着它不知道它指向什么(没有结构),只是它指向一些大小大小的内存。

在你调用 malloc 之外,你可以告诉你的程序这个指针有一些结构。即,如果你有一个结构some_struct,你可以说: struct some_struct *pStruct = (struct some_struct *) malloc(sizeof(struct some_struct)).

看看 malloc 如何只知道它要分配的大小,但实际上并不知道它的结构?您对 malloc 的调用没有传递有关结构的信息,只是传递了要分配多少内存的大小。

这是 C 语言的通用方式:malloc 返回一定数量的内存,您的工作是将其转换为您需要的结构化内存。

于 2012-12-25T19:30:05.930 回答
2
 p = (void *)malloc_ptr;

malloc返回一个 void 指针,表明它是一个指向未知数据类型区域的指针。由于强类型系统,仅在 C++ 中需要使用强制转换,而在 C 中则不需要。malloc根据一些程序员的说法,缺少返回的特定指针类型是类型不安全的行为:

malloc基于字节数而不是类型分配。

 malloc_ptr += size;

C 隐式转换 from 和 to void*,因此转换将自动完成。在 C++ 中,只有隐式转换为void*,而对于另一个方向,则需要显式转换。

关于类型转换的Wiki解释:malloc函数返回一个无类型的指针类型void *,调用代码必须将其转换为适当的指针类型。较旧的 C 规范需要显式转换才能做到这一点,因此代码

(struct foo *) malloc(sizeof(struct foo))

成为公认的做法。

但是,在 ANSI C 中不鼓励这种做法,因为它可以掩盖包含malloc定义的头文件的失败,从而导致 int 和指针类型具有不同大小的机器上的下游错误,例如现在无处不在的 x86_64 架构. 在编译为 C++ 所需的代码中会出现冲突,因为在该语言中强制转换是必需的。

于 2012-12-25T19:44:33.960 回答
1

正如你看到这两条线,

p = (void *)malloc_ptr;
malloc_ptr += size;

在这里,您的 malloc_ptr 类型为 unsigned long,因此我们将此变量类型转换为 void 类型,然后将其存储在 p 中。并且以类似的方式第二个表示 malloc_ptr = malloc_ptr + size;

这两个代码都是为了开发人员的舒适,因为 p 是 void 指针类型,所以在应用程序中,当你使用 malloc 时,你不知道函数必须返回哪种类型的内存块,所以这个函数总是返回这个通用的 void 指针所以我们可以根据要求在我们的应用程序中再次进行类型转换。

如果您输入的大小为负数,则在第二个代码中相同,那么这种情况会发生什么

if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr)
error("Out of memory");
于 2012-12-27T16:02:21.690 回答