我认为我无法像Java中的简单.length
函数那样检索已分配内存块的长度。但是,我现在知道当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);
}
**编辑: 我终于做到了。问题是,它持续给出0作为长度而不是我的系统上的大小是因为我的Ubuntu是64位。我将str-4更改为str-8,现在可以正常工作。
如果我将大小更改为2000,则会生成2017年的长度。但是,当我更改为3000时,它会给出3009.我正在使用GCC。
答案 0 :(得分:25)
您不必自己跟踪它!
size_t malloc_usable_size(void * ptr);
但它返回分配的内存块的实际大小! 不是你传给malloc的大小!
答案 1 :(得分:15)
你所做的绝对是错的。虽然几乎可以肯定,在分配的块之前的字与大小有关,但即使如此,它可能在未使用的位中包含一些额外的标志或信息。根据实现情况,此数据甚至可能位于高位,这会导致您读取完全错误的长度。此外,有可能将小分配(例如1到32个字节)打包到没有标题的特殊小块页面中,在这种情况下,分配块之前的单词只是另一个块的一部分,并且对于大小没有任何意义您要检查的区块。
请停止这种被误导和危险的追求。如果您需要知道malloc
获得的块的大小,那么您做错了。
答案 2 :(得分: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);
}
然后你总是可以通过减去sizeof(元数据)来检索分配的大小,将指针转换为元数据并执行元数据 - >大小:
Metadata* header = (Metadata*)(ptr - sizeof(Metadata));
printf("Size allocated is:%lu", header->size); // don't quote me on the %lu ;-)
答案 3 :(得分:7)
这不是标准C.但是,它应该适用于Windows操作系统,并且可能在其他操作系统上可用,例如Linux(msize?)或Mac(alloc_size?)。
size_t _msize(void * memblock);
_msize()返回堆中分配的内存块的大小。
查看此链接: http://msdn.microsoft.com/en-us/library/z2s077bc.aspx
答案 4 :(得分:6)
你不应该这样做。如果你想知道你分配了多少内存,你需要自己跟踪它。
查看返回给你的内存块之外(在malloc返回指针之前,或者在指针之后+你要求的字节数)将导致未定义的行为。对于给定的malloc实现,它可能在实践中有效,但依赖于它并不是一个好主意。
答案 5 :(得分:4)
这是依赖于实现的
答案 6 :(得分:2)
你最好不要试图做你正在做的事情!
AFAIK在分配块开始之前的内存内容未由C / C ++标准定义,因此最终会得到一个不可移植的解决方案。您必须自己跟踪内存块的长度。
答案 7 :(得分:1)
在我的(Ubuntu)系统上运行此应用程序说:
Length of str:1009
答案 8 :(得分:0)
您要分配的每个块都以块描述符开头。问题是,它取决于系统架构。 尝试为您自己的系统找到块描述符大小。试试看看你的系统malloc手册页。