L
lithiumcat
Hi,
maybe you remember me, some time ago I asked about how to store an
integer value into a void*, and I learned that doing pointer
arithmetic yeilding a pointer outside of an object (except the one-
after-last thingy) is undefined behaviour.
Actually I was trying to associate a function pointer with a key,
through an AVL tree that managed void* data. Function pointers can't
be stored in void* (that is, the standard does not garantee it works),
so I stored them in a dynamic array and that was the index in said
array that I wanted to store in the void* of the tree.
My frist thought was actually to store into the tree pointers to array
elements, instead of their index. The problem is, the array being
dynamic, realloc() might change its location, and then all the
pointers in my tree become invalid.
So I thought about putting in my tree pointers to array elements, and
then when realloc() changes the base, correct all the nodes of the
tree accordingly. Something like that:
fnptr* oldbase = base_of_dynamic_fnptr_array;
increase_dynamic_array_size();
fnptr* newbase = base_of_dynamic_fnptr_array;
if (oldbase != newbase)
for (void** storage_location in the tree for all nodes) {
fnptr* oldptr = *storage_location;
int index = oldptr - oldbase;
*storage_location = newbase + index; }
From what I googled this is the usual way of dealing with pointers to
elements inside a realloc()ed array, and I think it works just fine on
many platforms.
But is this garanteed to work? According to my (poor) understanding of
the standard, if realloc() returns the original pointer, then oldbase
and newbase are both valid pointers which compare equal, so there is
no problem. But if realloc() changes the location of the dynamic
array, oldbase becomes an invalid pointer. I think in that case
oldbase is garanteed to compare unequal with newbase, which is a valid
pointer, but using it to compute "index" is undefined, right?
And if the above code is not garanteed to work by the standard, is
there any portable way of handling dynamic arrays moved by realloc()?
(besides never using pointers to elements inside a dynamic array)
maybe you remember me, some time ago I asked about how to store an
integer value into a void*, and I learned that doing pointer
arithmetic yeilding a pointer outside of an object (except the one-
after-last thingy) is undefined behaviour.
Actually I was trying to associate a function pointer with a key,
through an AVL tree that managed void* data. Function pointers can't
be stored in void* (that is, the standard does not garantee it works),
so I stored them in a dynamic array and that was the index in said
array that I wanted to store in the void* of the tree.
My frist thought was actually to store into the tree pointers to array
elements, instead of their index. The problem is, the array being
dynamic, realloc() might change its location, and then all the
pointers in my tree become invalid.
So I thought about putting in my tree pointers to array elements, and
then when realloc() changes the base, correct all the nodes of the
tree accordingly. Something like that:
fnptr* oldbase = base_of_dynamic_fnptr_array;
increase_dynamic_array_size();
fnptr* newbase = base_of_dynamic_fnptr_array;
if (oldbase != newbase)
for (void** storage_location in the tree for all nodes) {
fnptr* oldptr = *storage_location;
int index = oldptr - oldbase;
*storage_location = newbase + index; }
From what I googled this is the usual way of dealing with pointers to
elements inside a realloc()ed array, and I think it works just fine on
many platforms.
But is this garanteed to work? According to my (poor) understanding of
the standard, if realloc() returns the original pointer, then oldbase
and newbase are both valid pointers which compare equal, so there is
no problem. But if realloc() changes the location of the dynamic
array, oldbase becomes an invalid pointer. I think in that case
oldbase is garanteed to compare unequal with newbase, which is a valid
pointer, but using it to compute "index" is undefined, right?
And if the above code is not garanteed to work by the standard, is
there any portable way of handling dynamic arrays moved by realloc()?
(besides never using pointers to elements inside a dynamic array)