void **参数使用固定数组值调用

时间:2011-10-04 17:52:07

标签: c void-pointers indirection multiple-indirection

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

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个制表符分隔的数值。

这里有一些东西我远离 grokking 关于间接和固定的大小数组因此我想知道一个固定大小的数组是否可以作为参数发送为void **(即使有一种信念的飞跃,阵列的大小将受到尊重。不同的问题。)


tl; dr version

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

为什么不允许这样做?

1 个答案:

答案 0 :(得分:2)

数组衰减为指向其第一个元素的指针,指向任何类型的指针都可以隐式转换为void*。其次,为了使数组访问正常工作,FetchValueArray需要知道每个数组元素的大小。您正在尝试传递void**,这是指向void*的指针,因此数组访问将每个元素视为具有void*的大小,这是错误的 - - 您的数组元素的大小为int,不一定与void*的大小相同。

所以void**错了。您需要传入void*,这意味着“指向未知类型的指针”。您不能在void*上使用数组索引,因为编译器不知道基础指向类型的大小。你需要帮助它。例如:

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]));

在这里,我们手动执行数组索引 - 我们将void*转换为char*,其具有已知的指向大小(1个字节),然后执行数组通过乘以每个元素的大小来抵消。结果是指向正确的内存位置的指针,这是sscanf所期望的。

但在这里要非常小心 - 我认为你应该重新考虑你的设计。编译器不知道函数的语义,因此无法验证您是否传递了正确的参数。在没有意识到的情况下插入意外的安全漏洞非常容易。想想你是否可以通过不同的设计来改善编译器可以更彻底地验证。