How to get the size of memory pointed by a pointer?

耗尽温柔 提交于 2019-12-06 16:12:19

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)));
}
chux - Reinstate Monica

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 functions

A 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).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!