Re: manipulating void* in array



On 13 Jul 2005 15:51:04 -0700, "Stijn van Dongen" <svd@xxxxxxxxxxxx>
wrote:

> A question about void*. I have a hash library where the hash create
> function accepts functions
> unsigned (*hash)(const void *a)
> int (*cmp) (const void *a, const void *b)
>
> The insert function accepts a void* key argument, and uses the
> functions above to store this argument. It returns something (linked to
> the key) that the caller can store a value in. The actual key argument
> is always of the same pointer type (as seen in the caller, say foo*).
>
> Now I would like to have a function, say hash_keys, which returns all
> keys in the hash as a pointer to a malloced array of void*. However,
> there is not really a type I can use. I see two possible solutions.
> The first is to typedef a struct containing a void pointer:
>
> typedef struct {
> void* pp;
> } genpp;
>
> and have hash_keys return genpp* (the size could be written in an int*
> argument
> to hash_keys). This would make accessing the keys cumbersome.
>
> Solution 2) is illegal C (I think), but it's tempting. hash_keys would
> construct an array of void*-sized elements and copy its key pointers
> there using char* arithmetic. It would return void* and the caller
> would cast it to foo**. For one thing, this assumes sizeof(void*) is
> sizeof(foo*) for all possible foo. For another, I see nothing in the
> standard on void* that would support any of this. However, it feels as
> if approach 2) is conceptually extremely similar to the first and I
> suspect it would work on nearly all platforms/compilers.
>
An array of void*, addressed as void**, and an array of struct
containing only void*, addressed as genpp*, are indeed similar. And in
fact are very likely (though not guaranteed) to be laid out the same.

But the individual element pointers, of type void* in either case, are
NOT guaranteed to be laid out the same as some other (data) pointer
type foo*. So treating either of these as (casting to) foo** and
trying to use it is not safe, and I know of systems, though only a
few, where it won't work. Note that even if different pointers are the
same size, their internal representations may be different, so
checking or veryifying size is not enough to be safe.

I'm not sure what you mean by "char* arithmetic" -- does the "hash"
(which sounds like it's actually a hash table) know about (remember?)
each thing stored in it, or is it packing (all or some of) them
(perhaps a buckets-worth) into a big array? I'm guessing the "hash"
knows only about void-pointers to things, and maybe their sizes, but
not their types? If so, the logical thing to do is to create and
return an array of void*, and the caller, who presumably knows the
type of what was (or should have been) stored, then converts that to a
foo* before using it, either by explicitly casting or implicitly by
assigning to its own (copy) pointer.

> The questions then are,
>
> 1. Did I miss another solution where hash_keys creates some array?
> 2. Is my assessment of 2) correct?
> 3. On what kind of platforms/compilers would 2) fail? Outside the scope
> of this newsgroup, I know, but perhaps some kind soul can comment.
>

- David.Thompson1 at worldnet.att.net
.



Relevant Pages

  • Re: segfault w/ block, but not file scope
    ... void foo{ ... possess by-reference arguments, even ordinary local variables ... The "value" of the array is a pointer to the array's ...
    (comp.lang.c)
  • Re: qsort semantics
    ... must pass a pointer to the first object of the array to be sorted. ... int cmp(const void *a, const void *b) { ... You cast a to "pointer to an array of N char". ...
    (comp.lang.c)
  • Re: A little help please
    ... Well I guess it would be if I didn't know I was passing an array of ints ... incrementing the pointer by nBytes I was pointing to next array element.? ... array to a void* using a static cast. ...
    (alt.comp.lang.learn.c-cpp)
  • Re: 2-dimensional arrays and functions
    ... Here are my examples again incase you missed it in this pointer pandemonium: ... int main{ ... dynamically created 2D array in ppArray ... void pArrayFunction; ...
    (alt.comp.lang.learn.c-cpp)
  • Re: Can I send char as array argument?
    ... Everything about programming I have learned ... > void main ... to it with a pointer. ... Your solution was to declare a 1-element array of char ...
    (comp.lang.c)