如何在malloc之后获取内存块长度?
我以为我无法检索分配的内存块的长度,就像Java中的简单.length
函数一样。 但是,我现在知道当malloc()
分配块时,它会分配额外的字节来保存包含块大小的整数。 该整数位于块的开头; 实际返回给调用者的地址指向刚超过此长度值的位置。 问题是,我无法访问该地址来检索块长度。
#include #include int main(void) { char *str; str = (char*) malloc(sizeof(char)*1000); int *length; length = str-4; /*because on 32 bit system, an int is 4 bytes long*/ printf("Length of str:%d\n", *length); free(str); }
**编辑:我终于做到了。 问题是,它持续给出0作为长度而不是我的系统上的大小是因为我的Ubuntu是64位。 我将str-4更改为str-8,现在可以正常工作了。
如果我将大小更改为2000,则会生成2017年的长度。 但是,当我改为3000时,它会给出3009.我正在使用GCC。
你在做什么绝对是错的。 虽然几乎可以肯定,在分配的块之前的字与大小有关,但即使如此,它可能在未使用的位中包含一些额外的标志或信息。 根据实现,这些数据甚至可能位于高位 ,这将导致您读取完全错误的长度。 此外,小分配(例如1到32个字节)可能被打包到没有标题的特殊小块页面中,在这种情况下,分配块之前的单词只是另一个块的一部分,并且对于大小没有任何意义您正在检查的块。
只要停止这种误入歧途和危险的追求。 如果您需要知道malloc
获得的块的大小,那么您做错了。
你不必自己跟踪它!
size_t malloc_usable_size(void * ptr);
但它返回分配的内存块的实际大小! 不是你传给malloc的大小!
我建议您通过编译和链接定义my_malloc()的文件然后覆盖默认值来创建自己的malloc包装器,如下所示:
// my_malloc.c #define malloc(sz) my_malloc(sz) typedef struct { size_t size; } Metadata; void *my_malloc(size_t sz) { size_t size_with_header = sz + sizeof(Metadata); void* pointer = malloc(size_with_header); // cast the header into a Metadata struct Metadata* header = (Metadata*)pointer; header->size = sz; // return the address starting after the header // since this is what the user needs return pointer + sizeof(Metadata); }
然后你总是可以通过减去sizeof(元数据)来检索分配的大小,将指针转换为元数据并执行元数据 – >大小:
Metadata* header = (Metadata*)(ptr - sizeof(Metadata)); printf("Size allocated is:%lu", header->size); // don't quote me on the %lu ;-)
这不是标准C.但是,它应该适用于Windows操作系统,并且可能在其他操作系统上可用,例如Linux(msize?)或Mac(alloc_size?)。
size_t _msize(void * memblock);
_msize()返回堆中分配的内存块的大小。
请看这个链接: http : //msdn.microsoft.com/en-us/library/z2s077bc.aspx
你不应该这样做。 如果你想知道你分配了多少内存,你需要自己跟踪它。
在返回给你的内存块之外(在malloc返回指针之前,或在指针之后+你要求的字节数之后)将导致未定义的行为。 对于给定的malloc实现,它可能在实践中有效,但依赖于它并不是一个好主意。
这取决于实现
你最好停止尝试做你想做的事!
AFAIK在分配块开始之前的内存内容不是由C / C ++标准定义的,因此最终会得到一个不可移植的解决方案。 您必须自己跟踪内存块的长度。
在我的(Ubuntu)系统上运行此应用程序说:
Length of str:1009
您分配的每个块都以块描述符开头。 问题是,它取决于系统架构。 尝试为您自己的系统找到块描述符大小。 试试看看你的系统malloc手册页。