I have a fixed-size array declared:
int vals[25];
And I'd like to send the array to a function which will assign the values of vals:
bool FetchValueArray(char* source, char* name, char* typeFormat, int count, void** destination)
{
int i;
char *t;
t=strstr(source,name);
if (t)
if (destination != NULL)
{
for (i = 0;i < count;i++)
sscanf(t,typeFormat,destination[i]);
return true;
}
return false;
}
This will essentially read everything at after a certain search string. For example:
FetchValueArray(source,"CONFIG=","%d",15,vals);
Where "CONFIG=" is in plain text, followed by 15 tab separated numeric values.
There's something here I'm far from grokking about indirection and fixed aized arrays thus I'd like to know if a fixed sized array can be sent as a parameter as void** (even if there is the leap of faith that the size of the array will be respected. Different issue.)
tl;dr version
int vals[25];
bool foo(int size,void** d);
foo(25,vals);
Why is this not allowed?
Arrays decay into pointers to their first elements, and pointers to any type can be implicitly cast to
void*. Secondly, in order for array access to work properly,FetchValueArrayneeds to know how large each array element is. You're trying to pass avoid**, which is a pointer to avoid*, so the array access treats each element as if it had the size of avoid*, which is wrong -- your array elements have sizeint, which is not necessarily the same as the size of avoid*.So
void**is wrong. You instead need to pass invoid*, which means "pointer to unknown type". You can't use array indexing on avoid*, since the compiler doesn't know the size of the underlying pointed-to type. You need to help it out. For example:Here, we're performing the array indexing manually -- we're casting the
void*tochar*, which has a known pointed-to size (1 byte), and then performing the array offset by multiplying by the per-element size. The result is a pointer to the proper memory location, which is whatsscanfexpects.Be very careful here, though -- I think you should reconsider your design. The compiler doesn't know the semantics of your function, so it can't verify that you're passing the proper arguments. It's very easy to insert an accidental security vulnerability without realizing it here. Think about if you might be better off with a different design that the compiler can verify more thoroughly.