Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
142 views
in Technique[技术] by (71.8m points)

c - Checking if a pointer is in a malloc'd area?

I'm making a dynamic memory allocator and I need to check than when I'm freeing a section of it, that the pointer I'm passing into the function is in fact within that area. I have a pointer to the beginning of the malloc'd area

typedef unsigned char byte;

static byte *memory // pointer to start of allocator memory

which I assign in my initiating function. I also have the size of the malloc'd area stored in

static u_int33_t memory_size;   // number of bytes malloc'd in memory[]

How do I ensure that the ptr isnt... (in pseudo code)

ptr < *memory || ptr > *memory + memory_size

and that code results in the following error;

error: comparison of distinct pointer types lacks a cast [-Werror] if ( object < memory || object > (memory + memory_size)) ^

I'm not sure what I need to cast and what not to...

The free function is as follows...

void memfree(void *object)
{
   if ( object < memory || object > (memory + memory_size)) {
  fprintf(stderr, "vlad_free: Attempt to free via invalid pointer
");
  exit(EXIT_FAILURE);
   }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Original

This is wrong as pointed out by Raymond Chen's answer

void memfree(void *_object)
{
   byte* object = (byte*)_object;
   if ( object >= memory && object < (memory + memory_size)) {
       /* defined guarantees - they happened to be in the same object. */
   } else {
      fprintf(stderr, "memfree: Attempt to free via invalid pointer
");
      exit(EXIT_FAILURE);
   }
}

The types of pointers need to be the same. Given that you seem to have a range in bytes, it seems best to use byte.

From the C standard n1570

When two pointers are compared, the result depends on the relative locations in the address space of the objects pointed to. If two pointers to object types both point to the same object, or both point one past the last element of the same array object, they compare equal. If the objects pointed to are members of the same aggregate object, pointers to structure members declared later compare greater than pointers to members declared earlier in the structure, and pointers to array elements with larger subscript values compare greater than pointers to elements of the same array with lower subscript values. All pointers to members of the same union object compare equal. If the expression P points to an element of an array object and the expression Q points to the last element of the same array object, the pointer expression Q+1 compares greater than P. In all other cases, the behavior is undefined.

Here, I believe the undefined behavior, is that you can't tell if on 2 systems, that there will be a consistent ordering, so code which uses a < b, may be true on some systems and false on others.

New answer

Use

void memfree(void *_object)
{
   uintptr_t object = (uintptr_t)_object;
   if ( object >= (uintptr_t)memory && object < ((uintptr_t)memory + (uintptr_t)memory_size)) {
       /* defined guarantees - they happened to be in the same object. */
   } else {
      fprintf(stderr, "memfree: Attempt to free via invalid pointer
");
      exit(EXIT_FAILURE);
   }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...