如何获取动态分配的内存大小?

时间:2015-02-26 06:20:33

标签: c linux data-structures malloc dynamic-memory-allocation

使用malloc动态分配内存将返回分配内存的地址。在该地址之前存储元数据;它是一个结构。

struct malloc_chunk {  
    int      prev_size;
    int      size;           // size of memory allocated
    struct malloc_chunk* fd;
    struct malloc_chunk* bk;
    struct malloc_chunk* fd_nextsize;
    struct malloc_chunk* bk_nextsize;
};

我想在不使用malloc_usable_size()的情况下打印大小值。我试过但是我遇到了段错误。我正在使用64位Ubuntu。

5 个答案:

答案 0 :(得分:4)

结构取决于实现。您根本不应该使用这些信息,因为它可能会在下一个编译器甚至下一个编译器版本中发生变化。

您应该管理用户定义结构中的内存大小。

修改 内存分配算法通常适用于某些对齐

  • 避免在进一步分配中使用未对齐的地址
  • 在允许未对齐访问但可能导致性能下降的架构上提供最佳性能
  • 使用多个基数的块来减少堆碎片,例如, 16个字节。

因此malloc不需要精确分配您作为参数传递的大小。它可以分配一个足以容纳所请求大小但可能更多的块。 malloc没有必要存储原始值,只需要free块的块大小。

因此,可能无法检索malloc函数调用中传递的size参数。

答案 1 :(得分:3)

在一般情况下,确切的机制malloc用于存储大小 - 如果它甚至有一个机制 - 将被实现定义。如果您需要任何特定的东西,您需要自己跟踪尺寸。

答案 2 :(得分:2)

首先,malloc_usable_size是Linux / Unix特有的功能,例如在Windows上不起作用。

因此,最好的方法是在分配内存时保存大小:只记住分配了多少内存,而不是使用该值。

答案 3 :(得分:1)

Malloc库通常在内部维护一个struct malloc_chunk列表,以管理到目前为止为用户提供的内存量。通常,为了应对这种情况,他们有办法将返回的指针从 malloc(3)映射到此结构的地址(因此 free(3)可以到达它),但你肯定不知道该映射。

通常,他们在内部分配金额来存储他们给你的内存和这个struct malloc_chunk,并且结构的对齐方式是他们可以从你传递给{{的指针获取结构地址。 1}}。

解决这个问题的正常方法是: malloc(3)函数为您提供free(3),其中(void *)(ref + 1)ref指针(所以它& #39; s对齐到这个结构的末尾)并且你必须做相反的事情来获得一个指向该结构的有效指针,即:struct malloc_chunk *(将指针转换为((struct malloc_chunk *)ptr - 1)指针,然后返回一个结构大小指向那里)

此表达式是struct malloc_chunk *的指针类型,因此您可以使用以下代码引用其字段:

struct malloc_chunk

我无法测试此代码,因为我的void *p = malloc(120); struct malloc_chunk *mc = (struct malloc_chunk *)p - 1; printf("prev_size: %d\n" "size: %d\n" "fb: %p\n" "bk: %p\n" "fw_nextsize: %p\n" "bk_nextsize: %p\n", mc->prev_size, mc->size, mc->fb, mc->bk, mc->fw_nextsize, mc->bk_nextsize); 实现并未在任何地方定义此<malloc.h>类型(或者我无法找到它)。如果您希望我能够重现您的环境,您必须提供您获得此类型的位置的参考。我正在使用struct malloc_chunk

答案 4 :(得分:1)

考虑以下测试代码(没有错误检查):

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

int main(void)
{
    void *v1 = malloc(160);
    void *v2 = malloc(160);
    void *v3 = malloc(160);

    printf("v1 = %p\n", v1);
    printf("v2 = %p\n", v2);
    printf("v3 = %p\n", v3);

    ptrdiff_t d1 = v2 - v1;
    ptrdiff_t d2 = v3 - v2;

    printf("d1 = %td\n", d1);
    printf("d2 = %td\n", d2);
    return 0;
}

在64位Ubuntu 14.04 LTS上编译时,得到的输出是:

v1 = 0x742010
v2 = 0x7420c0
v3 = 0x742170
d1 = 176
d2 = 176

由于返回块之间的间隙为176字节,分配的大小为160字节,因此只有16字节的开销。问题中概述的struct malloc_chunk在64位平台上占用40个字节(在32位平台上为24个字节)。它不适合分配的内存块之间的空间。

因此,任何从常规分配内存块访问struct malloc_chunk的尝试都注定要失败。

您必须获取malloc()的来源,以了解它如何使用该结构。如果我不得不猜测,它会在一个单独的区域中使用它。也许16个字节的开销中的一些告诉malloc()在哪里找到struct malloc_chunk。但这是猜测;我没看过。