2011-10-04 94 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所期望的。

雖然在這裏要非常小心 - 我認爲你應該重新考慮你的設計。編譯器不知道你的函數的語義,所以它不能驗證你是否傳遞了正確的參數。插入意外的安全漏洞非常容易,而不會在這裏實現。想一想,如果你使用不同的設計讓編譯器可以更徹底地驗證,你可能會更好。