简体   繁体   English

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

[英]How to get the size of the memory allocated dynamically?

Allocating memory dynamically using malloc will return the address from where the memory is allocated. 使用malloc动态分配内存将返回分配内存的地址。 Before that address meta-data is stored; 在该地址存储元数据之前; it's a struct. 这是一个结构。

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;
};

I want to print value of size without using malloc_usable_size(). 我想在不使用malloc_usable_size()的情况下打印size的值。 I tried but I am getting a segfault. 我尝试过,但是遇到了段错误。 I am working on 64-bit Ubuntu. 我正在使用64位Ubuntu。

The structure is implementation dependent. 该结构取决于实现。 You should not use the information at all since it might change at the next compiler or even at the next compiler version. 您完全不应使用该信息,因为它可能在下一个编译器甚至下一个编译器版本中发生变化。

You should manage the size of memory in user defined structures. 您应该在用户定义的结构中管理内存的大小。

Edit: Memory allocation algorithms usually work with some alignments to 编辑:内存分配算法通常与某些对齐方式一起使用

  • avoid unaligned addresses in further allocations 避免在进一步分配中使用未对齐的地址
  • provide best performance on architectures where unaligned access is allowed but could result in performance penalties 在允许不对齐访问的架构上提供最佳性能,但可能会导致性能下降
  • reduce the heap fragmentation be using chunks that are a multiple of a base, eg 16 bytes. 使用基数的倍数(例如16个字节)的块来减少堆碎片。

Therefore malloc doesn't need to allocate exactly the size that you passed as parameter. 因此, malloc不需要完全分配您作为参数传递的大小。 It can allocate a chunk the is sufficient to hold the requested size but probably more. 它可以分配一个块,足以容纳请求的大小,但可能更多。 It's not necessary for malloc to store the original value, only the chunk size is necessary to free the chunk. malloc不必存储原始值,只有块大小才需要free块。

Therefore it's probably impossible to retrieve the size parameter passed in the malloc function call. 因此,检索在malloc函数调用中传递的size参数可能是不可能的。

In the general case, the exact mechanism malloc uses to store the size -- if it even has a mechanism -- is going to be implementation defined. 在一般情况下, malloc用来存储大小的确切机制(即使它具有机制)将由实现定义。 You need to keep track of the size yourself if you need it for anything specific. 如果您需要任何特定的尺寸,则需要自己跟踪尺寸。

First of all malloc_usable_size is Linux/Unix specific function and will not work on Windows, for example. 首先, malloc_usable_size是Linux / Unix特定的功能,例如,在Windows上将不起作用。

So, the best way is to save size when allocating memory: just remember how much memory was allocated and than use that value. 因此,最好的方法是在分配内存时节省大小:只记得分配了多少内存,然后使用该值即可。

Consider the following test code (which has no error checking): 考虑以下测试代码(没有错误检查):

#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;
}

When compiled on 64-bit Ubuntu 14.04 LTS, the output I got was: 在64位Ubuntu 14.04 LTS上编译时,我得到的输出是:

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

Since the gap between the returned blocks is 176 bytes and the size allocated is 160 bytes, there are just 16 bytes of overhead. 由于返回的块之间的间隙为176个字节,分配的大小为160个字节,因此只有16个字节的开销。 The struct malloc_chunk outlined in the question occupies 40 bytes on a 64-bit platform (24 on a 32-bit platform). 问题中概述的struct malloc_chunk在64位平台上占用40个字节(在32位平台上占用24个字节)。 It does not fit into the space between allocated chunks of memory. 它不适合分配的内存块之间的空间。

Therefore, any attempt to access a struct malloc_chunk from a regular block of allocated memory is doomed to failure. 因此,任何从已分配内存的常规块访问struct malloc_chunk尝试注定会失败。

You will have to obtain the source to malloc() to find out how it uses that structure. 您将必须获取malloc()的源,以了解其如何使用该结构。 If I had to guess, it uses it in a separate area altogether. 如果我不得不猜测,它将完全在单独的区域中使用它。 Maybe some of the 16 bytes of overhead tells malloc() where to find the struct malloc_chunk . 也许16个字节的开销中的一些告诉malloc()在哪里找到struct malloc_chunk But that's a guess; 但这是一个猜测; I've not looked. 我没看

Malloc library normally maintains a list of struct malloc_chunk internally to manage the amounts of memory given to the user up to this point. Malloc库通常在内部维护struct malloc_chunk的列表,以管理到目前为止分配给用户的内存量。 Normally, to cope with that they have a way to map the returned pointer from malloc(3) to the address of this structure (so free(3) can get to it), but you don't know that mapping for sure. 通常,为了解决这个问题,他们有一种方法可以将malloc(3)返回的指针映射到该结构的地址(因此free(3)可以到达它),但是您不确定该映射。

Normally, they alloc internally the amount to store the memory they give to you and this struct malloc_chunk together, and the struct is aligned in a way that they can get the structure address from the pointer you pass to free(3) . 通常,它们在内部分配数量,以将它们提供给您的内存和该struct malloc_chunk一起存储,并且结构以它们可以从传递给free(3)的指针获取结构地址的方式对齐。

The normal way to cope with this is: The malloc(3) function gives you (void *)(ref + 1) , where ref is a struct malloc_chunk * pointer (so it's aligned to the end of this structure) and you have to do just the opposite to get a valid pointer to that structure, that is: ((struct malloc_chunk *)ptr - 1) (convert the pointer to a struct malloc_chunk * pointer, and then go back one structure size to point there) 解决此问题的通常方法是: malloc(3)函数为您提供(void *)(ref + 1) ,其中ref是一个struct malloc_chunk *指针(因此它与该结构的末尾对齐),您必须进行相反的操作以获取指向该结构的有效指针,即: ((struct malloc_chunk *)ptr - 1) (将指针转换为struct malloc_chunk *指针,然后返回一个结构大小以指向该结构)

This expression is of type pointer to struct malloc_chunk , so you can reference its fields with the following code: 该表达式的类型为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);

I have not been able to test this code, as my <malloc.h> implementation doesn't have this struct malloc_chunk type defined anywhere (or I have not been able to find it). 我无法测试此代码,因为我的<malloc.h>实现没有在任何地方定义此struct malloc_chunk类型(或者我无法找到它)。 You have to provide a reference of where do you have acquired this type if you want me to be able to reproduce your environment. 如果希望我能够重现您的环境,则必须提供有关在何处获得此类型的参考。 I'm using gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) 我正在使用gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM