2011-01-26 100 views
3

問題在頁面末尾回答。完整的工作代碼。C自動展開式指針陣列

你好,我想在C中做我在標題中提到的,但是,我不知道如何實現它。我已經在C++中完成了這一點,這要歸功於模板但是àla C。這裏是功能齊全的C++代碼:List.h (simple database)

* 我想知道如果用void指針我可以模擬代碼。問題是,我看到一個鏈接,指出應該避免void *,因爲它可能會導致比解決更多的麻煩。

基本上它是一個存儲指向變量本身的指針的「智能數組」。 如果我知道每個指針的大小和指向的每個結構的大小,那麼簡單的malloc和realloc應該正確嗎?

typedef struct 
{ 
    void **list; 

    // internal 
    int last_item_index; 
    size_t element_size; // size of each pointer 
    int elements;  // number of currently allocated elements 
    int total_size;  // >= #elements so that we don't have to always call malloc 
    int tweak_request_size; // each time the list grows we add this # of elements 

} List; 
// a shot at an addCopy function 
// it deepcopies the object you pass in 
List_addCopy(List *db, void *ptr_to_new_element) 
{ 
    ... // grow **list 
    // alloc and copy new element 
    db->list[db->last_item_index+1] = malloc(element_size); // WORKS? 
    // HOW TO COPY THE ELEMENT TO HERE IF IT IS A STRUCTURE FOR INSTANCE??? 
    ... 
} 

or 
// a shot at an assign function 
// (allocate the elements yourself then pass the pointer to the List) 
List_assign(List *db, void *ptr_to_new_element) 
{ 
    db->List = realloc(db->List, element_size*(elements+tweak_request_size)); 
    db->List[db->last_item_index+1] = ptr_to_new_element; 
} 

// Usage example 

List db; // our database 
struct funky *now = (funky*)malloc(sizeof(funky)); 

funky->soul = JamesBrown; 

List_addCopy(db, funky); 

if (list[0]->soul == JamesBrown) 
    puts("We did It! :D"); 

如果我在外面分配一切,只是將指針傳遞給列表我猜唯一的問題是void **。

List_add是否可能?只有使用回調來完成元素的分配和/​​或複製它?

List_assign可能嗎?我不想做很多工作,最終得到不可靠的軟件。

感謝在寫作卷積了很多,對不起:P

+0

如果你知道元素的大小,它是一個簡單的平面數據結構(沒有指向任何需要複製的指針),只需`memcpy`即可。 – 2011-01-26 01:30:46

+0

@Pemdas:我相信我確實提到過。 – 2011-01-26 02:33:48

回答

1

可避免void*像這樣的東西:

#include <stdio.h> 
#include <stdlib.h> 

#define List(T) \ 
    typedef struct { \ 
     T** items; \ 
     int count; \ 
    } List_ ## T ;\ 
    \ 
    List_ ## T * List_ ## T ## _New() { \ 
     List_ ## T * list = (List_ ## T *) malloc(sizeof(List_ ## T)); \ 
     list->count = 0; \ 
     return list; \ 
    } \ 
    \ 
    void List_ ## T ## _Add(List_ ## T *list, T * data) { \ 
     printf("%d\n", ++list->count); \ 
    } \ 
    void List_ ## T ## _Del(List_ ## T *list, int index) { \ 
     printf("%d\n", --list->count); \ 
    } 

/* define just one list per type */ 
List(int); 
List(double); 

int main() 
{ 
    int a, b, c; 
    double d, e; 
    List_int *l1; 
    List_double *l2; 

    l1 = List_int_New(); 
    List_int_Add(l1, &a); 
    List_int_Add(l1, &b); 
    List_int_Add(l1, &c); 
    List_int_Del(l1, 0); 
    List_int_Del(l1, 0); 
    List_int_Del(l1, 0); 

    l2 = List_double_New(); 
    List_double_Add(l2, &d); 
    List_double_Add(l2, &e); 
    List_double_Del(l2, 0); 
    List_double_Del(l2, 0); 

    return 0; 
} 

這是一個窮人的模板=)

上帝保佑

1

此處完全可以工作代碼

嗨,我用特立尼達和多巴哥的方法,因爲我不知道無效**會的工作,它是相當不錯的xD

它完美,但它是複雜的,以避免循環依賴(包括另一頭導致在「多重引用」中),而不會阻塞太多的接口,所以我放棄了這種方法,儘管我也上傳了它@SourceForge,然後我再次做了所有事情,這次用void指針並且它完美工作;)不用擔心包含一個頭兩次,等等。只是工作。

順便說一句,這裏的鏈接,用它在你的喜好:List - the smart && generic container

如有任何疑問使用幫助論壇,當我有時間,我會記錄它,但現在我用它爲我的項目。

祝你好運!