2014-07-01 40 views
1

我目前正在使用NUMA机器。我正在使用​​来释放我分配的内存。但是,与free不同,​​需要知道要释放多少个字节。有什么方法可以知道一个指针指向了多少个字节而没有将它指出来?如何获取指针指向的内存大小?

+0

知道它是完全尴尬(或不可能)。这是秘密的,可以“免费”知道。此外,如果你分配,那么你已经知道这一点。 –

+0

如果你正在使用malloc来分配内存,或者其他明智的你必须查找malloc在哪里存储它的元数据......在由malloc创建的元数据同时声明一块内存以供使用..它通常存储在该调用中分配的内存块大小... – PRP

回答

0

指针只是表示内存中的一个独特点,它通常是数据启动的地方。始终由开发人员来跟踪该位置提供了多少空间。 (free是规则的例外)。

1

如果您为单个值分配内存,则可能使用sizeof()来查找该值类型所需的空间量。你也应该知道这个类型是什么类型的,因为它是指针的类型。因此,您可以在同一类型上再次拨打sizeof()。 (例如,如果您分配sizeof(Foo)字节来存储到一个Foo*,那么你要释放sizeof(Foo)字节为好。)

如果为阵列分配的内存,您应该已经保持该数组的长度的轨道,例如以便在迭代时知道停止的位置。将该长度乘以单个元素类型的大小。

3

使用底层API无法获得内存大小。在分配某处时必须记住大小。例如,你可以写你自己的分配器,其分配4个额外的字节,存储在缓冲区的前4个字节大小,和释放过程中,你可以从中读取缓冲区的大小:之前

void *my_alloc(size_t size) 
{ 
    void *buff = numa_alloc_local(size + sizeof(size_t)); 
    if (buff == 0) return 0; 

    *(size_t *)buff = size; 
    return buff + sizeof(size_t); 
} 

void my_free(void *buf) 
{ 
    numa_free(buf - sizeof(size_t), *(size_t *)(buf - sizeof(size_t))); 
} 
+2

警告:该代码不可移植。考虑一台具有32位size_t的机器,但是对于双倍的64位对齐要求,比如ARM。您返回的指针将无法正确对齐。 – pdw

+0

是的,好点。那么,如果'numa_alloc_local'承诺以8字节对齐分配缓冲区,那么仍然可以改善这个代码分配额外的8个字节而不是4个。 –

2

存储分配大小内存指针报告。

@light_keeer有一个很好的解决方案/方法,但有潜在的对齐问题@pdw

my2_alloc(),与malloc()一样,可能会返回符合C规范的对齐要求的指针。同样,my2_alloc()也需要确保返回的指针符合对齐要求。

指针返回如果分配成功,则对齐适当,使得其可以被分配给一个指针到任何类型的对象与基本对准要求...
C11dr§7.22.3存储器管理功能

A 基本对齐由小于或等于实现在所有上下文中支持的最大对齐数的对齐表示,其等于_Alignof (max_align_t)。 §6.2.82

Follows是一个候选C99解决方案。

// Form a prefix data type that can hold the `size` and preserves alignment. 
// It is not specified which is type is wider, so use a union to allocate the widest. 
#include <stddef.h> 
union my2_size { 
    size_t size; 
    max_align_t a; 
} 

void *my2_alloc(size_t size) { 
    union my2_size *ptr = numa_alloc_local(sizeof *ptr + size); 
    if (ptr) { 
     ptr->size = size; 
     ptr++; 
    } 
    return ptr; 
} 

void my2_free(void *buf) { 
    if (buf) { 
     union my2_size *ptr = buf; 
     ptr--; 
     numa_free(ptr, sizeof *ptr + ptr->size); 
    } 
} 

// Return how many bytes are pointed to by a pointer allocated with my2_alloc() 
size_t my2_size(void *buf) { 
    if (buf) { 
     union my2_size *ptr = buf; 
     ptr--; 
     return ptr->size; 
    } 
    return 0; 
}