I saw this question fromwww.brainbench.com
void *ptr;
myStruct myArray[10];
ptr = myArray;
Which of the following is the correct way to increment the variable
"ptr"?
Choice 1 ptr = ptr + sizeof(ptr);
Choice 2 increment(ptr);
Choice 3 ++(int*)ptr;
Choice 4 ptr = ptr + sizeof(myArray);
Choice 5 ptr = ptr + sizeof(myStruct);
THEIR Correct Answer given in this site is: ptr = ptr +
sizeof(myStruct);
Who is 'THEIR'?
But my answer is ++(int*)ptr. The reason is that ptr being void *, we
cannot add any number to it. It must be cast to a valid object before
incrementing.
Which is correct ?
I would say "none of the above... maybe".
Choice 1 ptr = ptr + sizeof(ptr);
No, ptr is a void * and void has no size, thus it cannot move the
pointer and is considered an error.
This cannot work in C, there is no way of passing ptr by reference
unless you do so explicitly with the & operator.
This is the maybe as this may or may not produce an lvalue given
certain compilers. It is not recommended.
Choice 4 ptr = ptr + sizeof(myArray);
Same answer as Choice 1.
Choice 5 ptr = ptr + sizeof(myStruct);
Same answer as Choice 1.
That said, choice 2 and 3 are close, and could work if tweaked:
Choice 2
increment(ptr); // wrong, passing by value cannot change
ptr's value
increment(&ptr); // could work if increment takes a ** and
wraps what actually happens.
Choice 3
++(int*)ptr;
++*(int**)&ptr;
That said, my mod to choice 3 may not work either under some systems
as I think that I read somewhere that conversion of a pointer may not
work as there are special pointers to certain types. I.e. a int
pointer may not be the same as a double pointer. Unfortunately, I
don't remember the reference but should still work in most cases.
The safest bet is doing this:
int * intPtr = (int*)ptr;
++intPtr;
ptr = (void*)intPtr;
Which in my mind would be what is happening internally if you did +
+*(int**)&ptr; If increment is wrapped in a macro which does this,
than it would work. A more generalised macro would be:
#define increment(fromType, toType, ptr) do { \
toType * _tmpPtr_ = (toType*)ptr; \
++_tmpPtr_; \
ptr = (fromType*)_tmpPtr_; \
} while (0)
and then do this:
increment(void, int, ptr);
An increment function that assumes to increment a void pointer as if
it were an int would be:
void increment(void** prt)
{
int* intPtr = (int*)*prt;
++intPtr;
*ptr = (void*)intPtr;
}
but a more generalised solution would be this:
void increment(void** ptr, size_t size)
{
char* charPtr = (char*)*prt;
charPtr += size;
*ptr = (void*)charPtr;
}
the first would be used like:
increment(&ptr);
the second would be used like:
increment(&ptr, sizeof(int));
Does this make sense to you?
Adrian