Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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

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

1 Answer

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);
   }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share

548k questions

547k answers

4 comments

86.3k users

...