0

我声明了一个固定大小的数组:

int vals[25];

我想将数组发送到一个函数,该函数将分配 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;
}

这基本上会在某个搜索字符串之后读取所有内容。例如:

FetchValueArray(source,"CONFIG=","%d",15,vals);

其中“CONFIG=”是纯文本,后跟 15 个制表符分隔的数值。

这里有一些东西我远非对间接和固定的aized数组感到好奇,因此我想知道是否可以将固定大小的数组作为 void** 的参数发送(即使有信仰的飞跃,即数组将受到尊重。不同的问题。)


tl;博士版

int vals[25];
bool foo(int size,void** d);
foo(25,vals);

为什么不允许这样做?

4

1 回答 1

2

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, FetchValueArray needs to know how large each array element is. You're trying to pass a void**, which is a pointer to a void*, so the array access treats each element as if it had the size of a void*, which is wrong -- your array elements have size int, which is not necessarily the same as the size of a void*.

So void** is wrong. You instead need to pass in void*, which means "pointer to unknown type". You can't use array indexing on a void*, since the compiler doesn't know the size of the underlying pointed-to type. You need to help it out. For example:

bool FetchValueArray(char* source, char* name, char* typeFormat, int count, void* destination, size_t destElementSize)
{
    ...
    sscanf(t, typeFormat, (char*)destination + destElementSize * i);
    ...
}
...
FetchValueArray(source, "CONFIG=", "%d", 15, vals, sizeof(vals[0]));

Here, we're performing the array indexing manually -- we're casting the void* to char*, 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 what sscanf expects.

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.

于 2011-10-04T18:07:31.217 回答