c-如何获得动态分配的内存大小



使用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上工作。

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

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

编辑:内存分配算法通常与进行一些比对

  • 在进一步的分配中避免未对齐的地址
  • 在允许未对齐访问但可能导致性能损失的体系结构上提供最佳性能
  • 通过使用基数的倍数(例如16字节)的块来减少堆碎片

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

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

在一般情况下,malloc用于存储大小的确切机制(如果它有机制的话)将由实现定义。如果你需要任何特定的尺寸,你需要自己记录尺寸。

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

#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 = %pn", v1);
    printf("v2 = %pn", v2);
    printf("v3 = %pn", v3);
    ptrdiff_t d1 = v2 - v1;
    ptrdiff_t d2 = v3 - v2;
    printf("d1 = %tdn", d1);
    printf("d2 = %tdn", 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。但这只是猜测;我没有看。

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

因此,最好的方法是在分配内存时节省大小:只需记住分配了多少内存,然后使用该值。

Malloc库通常在内部维护一个struct malloc_chunk列表,以管理到目前为止提供给用户的内存量。通常,为了应对这种情况,他们有一种方法将返回的指针从malloc(3)映射到这个结构的地址(所以free(3。

通常,它们在内部分配数量,以将它们提供给您的内存和这个struct malloc_chunk存储在一起,并且结构是对齐的,这样它们就可以从您传递给free(3)的指针中获得结构地址。

处理此问题的正常方法是:malloc(3)函数为您提供(void *)(ref + 1),其中ref是一个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:   %dn"
       "size:        %dn"
       "fb:          %pn"
       "bk:          %pn"
       "fw_nextsize: %pn"
       "bk_nextsize: %pn",
       mc->prev_size,
       mc->size,
       mc->fb,
       mc->bk,
       mc->fw_nextsize,
       mc->bk_nextsize);

我还没能测试这个代码,因为我的<malloc.h>实现在任何地方都没有定义这个struct malloc_chunk类型(或者我找不到它)。如果你想让我重现你的环境,你必须提供你在哪里获得这种类型的参考。我正在使用gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)

相关内容

  • 没有找到相关文章

最新更新