确定C中dynamic分配内存的大小
有没有办法在C中找出dynamic分配内存的大小?
例如,之后
char* p = malloc (100);
有没有办法找出与p
关联的内存大小?
comp.lang.c常见问题列表·问题7.27 –
问:那么我可以查询malloc
包来查明分配的块有多大?
答:不幸的是,没有标准或便携的方式。 (有些编译器提供非标准的扩展。)如果你需要知道,你必须自己跟踪它。 (另见问题7.28 )
没有标准的方法来find这个信息。 但是,一些实现提供像msize
这样的function。 例如:
- 在Windows上_msize
- 在MacOS上的malloc_size
- 带有glibc的系统上的malloc_usable_size
请记住,malloc将分配最小的请求大小,所以你应该检查你的实现的msizevariables是否实际返回对象的大小或堆中实际分配的内存。
C的心态是给程序员提供帮助他工作的工具,而不是提供改变他工作性质的抽象。 C还试图避免让事情变得更容易/更安全,如果这是以牺牲性能限制为代价的。
您可能想要对某个区域的内存进行某些操作只需要该区域开始的位置。 这样的事情包括使用空终止的string,操纵该区域的前n个字节(如果该区域已知至less是这么大),等等。
基本上,跟踪一个区域的长度是额外的工作,如果C自动完成,它有时会不必要地做。
许多库函数(例如fread()
)需要一个指向区域开始的指针,以及这个区域的大小。 如果你需要一个区域的大小,你必须跟踪它。
是的,malloc()实现通常会跟踪一个区域的大小,但是它们可能会间接地执行此操作,或者将它舍入到某个值,或者根本不保留它。 即使他们支持它,与自己追踪它相比,以这种方式查找大小可能会比较慢。
如果你需要知道每个地区有多大的数据结构,C可以为你做。 只需使用一个结构来跟踪区域的大小以及指向区域的指针。
不,C运行时库不提供这样的function。
某些库可能提供可获取此信息的特定于平台或编译器的函数,但通常跟踪此信息的方法是在另一个整数variables中。
我希望这是实施相关的。
如果你有头文件的数据结构,你可以把它重新放在指针上并获得大小。
此代码可能在大多数Windows安装上都可以使用:
template <class T> int get_allocated_bytes(T* ptr) { return *((int*)ptr-4); } template <class T> int get_allocated_elements(T* ptr) { return get_allocated_bytes(ptr)/sizeof(T); }
就像其他人已经说过的那样:没有。
另外,我总是会避免所有特定于供应商的function,因为当您发现您确实需要使用它们时,这通常意味着您做错了。 您应该单独存储大小,或者不必知道它的大小。 使用供应商function是最快的方式,失去了写在C,便携性的主要好处之一。
不,没有。
这可能工作,你的代码中的一个小的更新:
void* inc = (void*) (++p) size=p-inc;
但是,这将导致1,即与p
关联的内存,如果它是char*
。 如果它是int*
那么结果将是4。
没有办法找出总分配。
这是我见过的创build标记指针以存储地址大小的最佳方式。 所有指针函数仍然按预期工作:
从以下url窃取: https : //stackoverflow.com/a/35326444/638848
你也可以为malloc实现一个包装器,并在malloc返回的指针之前自由地添加标签(比如分配的大小和其他元信息)。 这实际上是c ++编译器通过引用虚拟类来标记对象的方法。 这是一个工作的例子:
#include <stdlib.h> #include <stdio.h> void * my_malloc(size_t s) { size_t * ret = malloc(sizeof(size_t) + s); *ret = s; return &ret[1]; } void my_free(void * ptr) { free( (size_t*)ptr - 1); } size_t allocated_size(void * ptr) { return ((size_t*)ptr)[-1]; } int main(int argc, const char ** argv) { int * array = my_malloc(sizeof(int) * 3); printf("%u\n", allocated_size(array)); my_free(array); return 0; }
这种方法相对于具有大小和指针的结构的优点
struct pointer { size_t size; void *p; };
是你只需要更换malloc和免费电话。 所有其他的指针操作都不需要重构。
如果你使用malloc,那么你不能获得大小。
另一方面,如果使用OS API来dynamic分配内存,如Windows 堆函数 ,那么可以这样做。
那么现在我知道这不是回答你的具体问题,不pipe是在盒子外面去思考,而是在我看来,你可能不需要知道。 好吧,不,我不是说你有一个坏的或不正统的实现…我的意思是说,你可能(不看你的代码,我只是猜测)你可能只想知道你的数据是否可以适合在分配的内存中,如果是这种情况,那么这个解决scheme可能会更好。 它不应该提供太多的开销,并将解决你的“适合”的问题,如果这确实是你正在处理的:
if ( p != (tmp = realloc(p, required_size)) ) p = tmp;
或者如果你需要保留旧的内容:
if ( p != (tmp = realloc(p, required_size)) ) memcpy(tmp, p = tmp, required_size);
当然你可以使用:
p = realloc(p, required_size);
并完成它。
int *a; a=malloc(n*sizeof(int));
如果malloc返回NULL意味着你没有获得内存,否则你得到的是分配块的基地址,意思是(n*sizeof(int))
块大小。
我不确定,但尝试:
char **q = &p; int size = q[1] - q[0];