首页 > 解决方案 > 了解堆中的内存分配

问题描述

我试图了解如何使用 malloc 在堆上分配内存,并遇到以下观察结果,但无法理解其背后的原因。如果有人可以解释,那就太好了。

首先,让我们看一下我写的代码:

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

void print_int_heap(unsigned int *ptr, int len)
{
    printf("PREV_SIZE: [%08x]  SIZE: [%08x]  MEM: [%08x] for INT malloc(%d)\n", *(ptr-2), *(ptr-1), ptr, len);
}
void print_char_heap(char *ptr, int len)
{
    printf("PREV_SIZE: [%08x]  SIZE: [%08x]  MEM: [%08x] for CHAR malloc(%d)\n", *(ptr-2), *(ptr-1), ptr, len);
}

int main() {

    unsigned int *ptr1 = malloc(20);
    print_int_heap(ptr1, 20);
    char *ptr2 = malloc(20)
    print_char_heap(ptr2, 20);
    return 0;
}

我为上述程序得到的输出是:

PREV_SIZE: [0x00000000] SIZE: [0x00000019] MEM: [0x0804b008] for INT malloc(20)
PREV_SIZE: [0x00000000] SIZE: [0x00000000] MEM: [0x0804b020] for INT malloc(20)

我可以理解 int malloc 的输出,但我不明白为什么 char malloc 的块大小的值为 0?

标签: cmemory-managementheap-memory

解决方案


Ifptr是一个int*,*(ptr - 1)指的是什么引用sizeof(int)之前的字节。ptr这通常是一个 32 位的数量,从 . 之前的四个字节开始ptr

类似地,如果它是 a char**(ptr - 1)则指在什么引用sizeof(char)之前的字节。始终为 1;通常这将是值之前的单个字节中的 8 位数量。ptrsizeof(char)ptr

这些显然是完全不同的东西。

顺便说一句,你可以写ptr[-1]。但正如上面的分析所示,这真的不是你想要的。您想强制ptr转换为指向您认为ptr可能是之前的对象的数据类型的指针uint32_t

从技术上讲,这都是未定义的行为,但是如果您的malloc实现是在分配之前存储数据并且您知道该数据的类型,我会说可以阅读它。(虽然盯着系统函数的内部数据看总是有点粗鲁。)

请注意,并非所有malloc实现都做同样的事情。您很可能会在其他地方找到一个长度或根本没有的。


推荐阅读