AnsweredAssumed Answered

Bad pointer math

Question asked by Peter LaDow on Oct 23, 2009
Latest reply on Oct 27, 2009 by Peter LaDow

I've got some code that calculates a pointer.  In one case I always get an offset from 0 (NULL), but the other always works correctly.  Let me post the code and I'll explain the problem:

 

 


typedef struct
{
  unsigned char pop_index;  ///< Pop index
  unsigned char push_index; ///< Push index
  void          *start;     ///< Pointer to underlying storage
  unsigned char reclen;     ///< Record size
  unsigned char used;       ///< Number of entries used
  unsigned char mask;       ///< Mask of the number of records
} queue_t;

queue_status_t queue_pop(queue_t *q, void *p){                         const unsigned char *src;  if ( q->used == 0 )  {    return Q_EMPTY;  }  if ( p != NULL )  {    src=(const unsigned char *)(q->start) + ((q->pop_index & q->mask) * q->reclen);     (void)memcpy(p, src, q->reclen);  }  q->pop_index++;  q->used--;  return Q_OK;}queue_status_t queue_push(queue_t *q, const void *p){  unsigned char *dst;  if ( q->used == q->mask )  {    return Q_FULL;  }  dst = (unsigned char *)(q->start) + ((q->push_index & q->mask) * q->reclen);   (void)memcpy(dst, p, q->reclen);  q->push_index++;  q->used++;  return Q_OK;}

 

Now, the problem is in queue_pop().  Every time I run this, the pointer 'src' is always offset from 0, regardless of the value of q->start.  But queue_push() works fine.  Now they have the exact same pointer math, they just use different values for the offsets.

 

However, if I change queue_push() to the following:

 

 


queue_status_t queue_pop(queue_t *q, void *p){                         const unsigned char *src=(const unsigned char *)(q->start);  if ( q->used == 0 )  {    return Q_EMPTY;  }  if ( p != NULL )  {    src += ((q->pop_index & q->mask) * q->reclen);     (void)memcpy(p, src, q->reclen);  }  q->pop_index++;  q->used--;  return Q_OK;}

 

It works fine.  Note that q->start is not NULL when I come into the function.

 

Any ideas what is occuring here?  I've had a few co-workers look over the code, and they can't seem to find anything in the code that would cause this to occur.

Outcomes