2011-10-04 58 views
0

我有一个固定大小的数组无效**参数声明:称为具有固定阵列值

int vals[25]; 

而且我想在阵列发送到将分配丘壑的值的函数:

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;博士版本

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

这是为什么不允许?

+1

传递给函数时,数组衰减为指针。是的,你可以把它当作'void *'。我不确定你为什么试图使用'void **'来代替。 – Mahesh

回答

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所期望的。

虽然在这里要非常小心 - 我认为你应该重新考虑你的设计。编译器不知道你的函数的语义,所以它不能验证你是否传递了正确的参数。插入意外的安全漏洞非常容易,而不会在这里实现。想一想,如果你使用不同的设计让编译器可以更彻底地验证,你可能会更好。