我以为我无法像.lengthJava中的简单函数那样检索分配的内存块的长度.但是,我现在知道,在malloc()分配块时,它会分配额外的字节来保存包含块大小的整数.该整数位于块的开头; 实际返回给调用者的地址指向刚刚超过此长度值的位置.问题是,我无法访问该地址来检索块长度.
#include <stdlib.h>
#include <stdio.h>
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);
}
Run Code Online (Sandbox Code Playgroud)
**编辑:我终于做到了.问题是,它持续给出0作为长度而不是我系统上的大小是因为我的Ubuntu是64位.我将str-4更改为str-8,现在可以使用了.
如果我将大小更改为2000,则会生成2017年的长度.但是,当我改为3000时,它给出3009.我正在使用GCC.
小智 25
你不必自己跟踪它!
size_t malloc_usable_size(void*ptr);
但它返回分配的内存块的实际大小!不是你传给malloc的大小!
R..*_*R.. 16
你在做什么绝对是错的.虽然几乎可以肯定,在分配的块之前的字与大小有关,但即使如此,它可能在未使用的位中包含一些额外的标志或信息.根据实现,这些数据甚至可能位于高位,这将导致您读取完全错误的长度.此外,有可能将小分配(例如1到32个字节)打包到没有标题的特殊小块页面中,在这种情况下,分配块之前的单词只是另一个块的一部分,并且对于大小没有任何意义您要检查的块.
只要停止这种被误导和危险的追求.如果您需要知道所获得的块的大小malloc,那么您做错了.
Mik*_*e M 13
我建议您通过编译和链接定义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);
}
Run Code Online (Sandbox Code Playgroud)
然后你总是可以通过减去sizeof(元数据)来检索分配的大小,将指针转换为元数据并执行元数据 - >大小:
Metadata* header = (Metadata*)(ptr - sizeof(Metadata));
printf("Size allocated is:%lu", header->size); // don't quote me on the %lu ;-)
Run Code Online (Sandbox Code Playgroud)
小智 7
这不是标准C.但是,它应该适用于Windows操作系统,也可以在其他操作系统上使用,例如Linux(msize?)或Mac(alloc_size?).
size_t _msize(void*memblock);
_msize()返回堆中分配的内存块的大小.
请看这个链接:http: //msdn.microsoft.com/en-us/library/z2s077bc.aspx
你不应该这样做.如果你想知道你分配了多少内存,你需要自己跟踪它.
在返回给你的内存块之外(在malloc返回指针之前,或者在指针之后+你要求的字节数之后)将导致未定义的行为.对于给定的malloc实现,它可能在实践中有效,但依赖于它并不是一个好主意.