【问题标题】:Memory allocation with malloc in C在 C 中使用 malloc 分配内存
【发布时间】:2012-10-10 23:40:18
【问题描述】:

这是我的程序:

#include <stdio.h>
#include <stdlib.h>

main(){
   char *p1, *p2, *p3, *p4;

   p1 = (char*)malloc(10);
   p2 = (char*)malloc(10);
   p3 = (char*)malloc(16);
   p4 = (char*)malloc(32);

   printf("p1 points at: %d\n", p1);
   printf("p2 points at: %d\n", p2);
   printf("p3 points at: %d\n", p3);
   printf("p4 points at: %d\n\n", p4);

   system("PAUSE");
}

这会在我的电脑上产生以下输出:

p1 指向:6492080

p2 指向:6492104

p3 指向:6492128

p4 指向:6492152

因此,无论分配多少字节,malloc 分配的每个内存空间都从 24 个字节开始。这是为什么?我感谢您的帮助!

【问题讨论】:

  • 编译器应该警告你,你的 %d 格式字符串。使用 %p 打印指针。您是否启用了警告?另外,不要从 malloc 中转换返回值。

标签: c memory pointers malloc


【解决方案1】:

malloc 的确切行为取决于您的特定实现(编译器/libc/OS)。通过打印出地址,您的程序将从事未定义的行为。

如果您通过告诉我们您正在使用什么编译器、您在什么操作系统、什么架构以及您正在使用什么版本的 libc 来缩小您的问题范围,那么我们也许可以给出更具体的答案那个实现以及为什么这个数字是 24。

我的 GUESS 会是,在您的实现中,每个 malloced 内存区域需要从一个 8 倍数的地址开始,并且还有 8 个字节的开销。

编辑:如果您在 p4 之后再次调用 malloc 以创建 p5,则该模式肯定无法继续,因此您的声明“malloc 分配的每个内存空间进一步开始 24 个字节,无论如何分配了很多字节。”是假的。

【讨论】:

  • 好的,我在 Windows 7 64 位操作系统上使用 Dev-C++ 编译器 v.4.9.9.2。我在哪里可以找到 libc 版本?最后,我理解我在这个问题上的错误,但你明白了!
【解决方案2】:

不保证int 和一些void*char* 指针大小相同(在我的Debian/Linux/AMD64 系统上,int-s 是32 位,但指针是64 位) .您可能想要包含&lt;stdint.h&gt; 并使用intptr_t

malloc 的实现有时可能会在分配的区域之前保留几个字节以用于内务管理。并且malloc 应该总是返回一个足够对齐的指针(alignment 约束是编译器、运行时和处理器特定的)。绝对不能保证malloc 会及时返回越来越多的结果序列(尤其是在实际程序中,对malloc 的数百万次调用与对free 的数百万次调用混合在一起;你甚至可能有一些memory fragmentation在如此长时间运行的过程中)。

而且我很确定,如果您在 p4 之后添加 p5 = malloc(10120);,您将不会看到 p5p4 之间的 24 字节距离,因为当它成功时 malloc 保证它result 不是任何先前结果的alias,因此p5p4 的距离至少应为32 字节(其中包含一个32 字节的块)。

几乎总是,标准 C 库在一些较低级别的原语之上实现 malloc,通常是一些 syscall 以获取连续的 virtual memory 页面。在 Linux 上,这些系统调用通常是 mmap(2)(可能是 sbrk(2)),并且由于 Linux 系统大多是 free software,您实际上可以研究和改进 malloc 的实现,例如Musl Libc implementation of malloc(更常见的 GNU libc malloc 实现可能更难理解)。因此,您可以通过切换到 Linux 来了解更多信息。

malloc 的实现理论上可以always fail。在实践中,malloc 可能会成功,但您应该始终测试失败的情况。

当然,大多数实现都关心free 并在最近的free-d 内存区(没有任何系统调用)中重用,如果可能的话,在他们的malloc 实现中。如何组织堆以使mallocfree 高效是困难的(如果您希望它非常好,可能仍然是一个研究课题)。

您可能想阅读malloc 上的维基百科页面。

【讨论】:

    【解决方案3】:

    malloc 应为size 大小的对象分配空间。例如,没有什么可以阻止您的实现为对齐目的添加填充字节。另一个例子:一些内存管理实现在分配空间之前保持块的大小。

    如果您想了解更多详细信息,则应精确实施。

    【讨论】:

      猜你喜欢
      • 2018-10-16
      • 1970-01-01
      • 2020-11-01
      • 2020-12-14
      • 1970-01-01
      • 2015-11-09
      • 2021-06-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多