我有一个关于释放指针的理论问题。
我认为某个人(程序本身或操作系统)必须跟踪它们的指针和长度。为什么?
float* pointer1 = malloc( 100 * sizeof(float) );
例如:我这里有一个浮点指针。有人能告诉我 pointer1 数组的长度是多少?在运行时调用函数/方法无法获得该指针的长度吗?那么程序(或操作系统)如何能够在运行时不知道指针的实际长度的情况下释放指针的内存部分:
free(pointer1);
如果程序知道指针的空闲长度,为什么我们无法获取该信息并使用其他方法来跟踪长度。例如:
struct floatArray
{
float* pointer;
int length;
}
所以,我对这个问题非常好奇。我真的想学习操作系统如何处理指针长度。
谢谢,
Sait的。
答案 0 :(得分:4)
内存管理器确实维护了每个已分配内存块的元数据。除了块的大小外,这可能还包含信息。
实现此目的的一种常见方法是将元数据存储在用户程序用于引用块的内存地址下方的内存中。因此,如果对malloc的调用返回地址p
,并且元数据包含n
个字节,则元数据将存储在地址p-n
到p-1
中。
答案 1 :(得分:2)
它通常不是直接操作系统,而是malloc()
实现 - 内存管理器,它从操作系统获取更大的内存块。通常,此信息将存储在某个链接列表中,但我建议您查看您的libc malloc()
以查看此信息的存储方式。
正如所指出的那样,没有一种标准的方法可以做到这一点,因为不同编译器/标准C库之间的实现方式各不相同 -
答案 2 :(得分:1)
操作系统不一定跟踪您请求的确切长度。由于各种内部原因,长度经常被改变(增加),或者以访问缓慢的方式存储。它可能具有编码在其中的附加信息(通常大小与2的幂的倍数和用作标志的低位对齐)。一些malloc实现(特别是嵌入式实现)根本就不实现free()
,也不需要存储这些信息。
C语言设计者希望允许C库实现的这种自由,因此他们不允许程序检索malloc缓冲区的大小。
答案 3 :(得分:1)
使用MSVC或MinGW,您可以使用(非标准!)函数_msize
float* pointer1 = malloc( 100 * sizeof(float) );
printf("%lu bytes with %lu elements", (unsigned long)_msize(pointer1),(unsigned long)_msize(pointer1)/sizeof*pointer1);