2016-03-06 82 views
0

所以我應該實現一個可以包含任何類型的對象在C中的集合。我如何根據該對象的類型動態分配內存。也就是說,如何只給出一個指向它的空指針來找出其類型未知的對象的大小?在c中動態分配內存與未知類型

void set_add(set *s, const void *item) { 
    ... 
    s->items[s->size] = malloc(sizeof(*item) * ??); 
    ... 
} 
+2

無法傳遞大小,無法找到以便攜方式指向的對象的大小。 –

+2

也許您的任務並沒有說明如何維護一個充滿*件*項目的集合。只要'const void *'指向的內容的生命週期/長度超過你的設置,並且身份是基於地址的,你就知道它的大小;它是'const void *'的大小。如果作業確實需要複製,則需要知道大小。沒有逃脫的。 – WhozCraig

+0

函數調用之前,你的'set * s'作爲一個參數保證包含正確的's-> size'嗎? –

回答

0

除非將尺寸傳遞給set_add函數,否則不能。

什麼你知道是指向對象的指針的大小,但。因此,不必存儲指向對象的副本,您可能應該擁有該對象的所有權(因此,當您不再需要時,它將負責對其進行處理),並將指針存儲到您的集合中的對象。

struct set { 
    void **items; 
    size_t free_space; 
    size_t capacity; 
}; 

void set_add(set * s, void * obj) { 
    // dedupe logic 
    assert(! (s->free_space > s->capacity)); 
    if (s->free_space == s->capacity) { 
    void ** new_items = realloc(s->items, s->capacity * 2); 
    // error handling please! 
    s->items = new_items; 
    s->capacity *= 2; 
    } 
    s->items[s->free_space++] = obj; 
} 

注意,我犧牲了const,因爲我做了items非const了。否則free會在通過const限定指針(目標)時發生抱怨。另一種可能性是在free之前刪除const。取決於你想達到的目標。

+1

我不確定*「你不能」*注意是否正確。看問題'set * s'作爲參數傳遞,'s-> size'成員似乎包含所需的大小。 OP值得確認一個問題。當它坐下時,你確定'尺寸'是必需的,但它是否已經被提供是不明確的。 –

+0

事實上,儘管我會假定size成員保存了該集合的當前大小,而不是元素的(那麼對於所有元素常量)大小。 @ DavidC.Rankin –