I am currently working on a NUMA machine. I am using numa_free
to free my allocated memory. However, unlike free
, numa_free
needs to know how many bytes are to be freed. Is there any way to know that how many bytes are pointed to by a pointer without tracing it out?
There is no way to obtain memory size using underlying API. You must remember size during the allocation somewhere. For Example, You may write your own allocator, that allocates 4 extra bytes, stores in first 4 bytes size of buffer, and during deallocation you can read size of buffer from it:
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)));
}
Store the allocation size just before the memory pointer reported.
@light_keeer has a good solution/approach, yet suffers from potential alignment problems @pdw.
my2_alloc()
, like malloc()
, presumably returns a pointer that meets alignment requirements of the C spec. Likewise, my2_alloc()
also needs to insure the returned pointer meets alignment requirements.
The pointer returned if the allocation succeeds is suitably aligned so that it may be assigned to a pointer to any type of object with a fundamental alignment requirement ...
C11dr §7.22.3 Memory management functionsA fundamental alignment is represented by an alignment less than or equal to the greatest alignment supported by the implementation in all contexts, which is equal to
_Alignof (max_align_t)
. §6.2.8 2
Follows is a candidate C99 solution.
// 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;
}
If you allocated memory for a single value, you probably used sizeof()
to find the amount of space needed for that value's type. You should know what that type was, too, because it's the type of the pointer. So you can just call sizeof()
again on the same type. (For example, if you allocated sizeof(Foo)
bytes to store into a Foo*
, then you want to free sizeof(Foo)
bytes as well.)
If you allocated memory for an array, you should already be keeping track of the length of that array, e.g. so that you know where to stop when iterating. Multiply that length by the size of the individual element type.
A pointer just indicates a distinct point in memory, which is usually where your data starts. It is always up to the developer to keep track of how much space has been made available at that location. (free
is an exception to the rule).
来源:https://stackoverflow.com/questions/24509509/how-to-get-the-size-of-memory-pointed-by-a-pointer