[英]Dynamic array with void pointer
所以在C和我學習指針認為,作為一個練習,我可以做一些通用數組,我得到它使用void **這樣:
struct array{
void **data;
size_t size, capacity;
};
插入這樣的元素:
void array_append(array *a, void *element){
if(a->size == a->capacity){
a->capacity += ARRAY_GROW_CONSTANT;
a->data = realloc(a->data, sizeof(void*)*a->capacity);
}
a->data[a->size++] = element;
}
但這並不是很好。 該數組存儲指向元素的指針,因此當元素的范圍結束時,它變為無效,並且它還使數組的內容分散在整個內存中。 我認為這可以通過分配元素本身來解決
a->data[a->size++] = element;
我會做點什么的
a->data[a->size] = malloc(inserted_element_size);
memcpy(a->data[a->size], &element, inserted_element_size);
size++;
但我認為當使用普通的void *而不是void **時我可以獲得相同的功能
struct array{
void *start;
size_t element_size, size;
};
和插入元素
void array_append(array *a, void *element){
a->size += 1;
a->data = realloc(a->data, (a->size*a->element_size));
memcpy(a->data + (a->size - 1)*a->element_size, &element, a->element_size);
}
但這導致了段錯誤,我不知道為什么。 據我所知(顯然我沒有),指針是內存中的地址,所以如果我有一個連續的內存塊,我可以用偏移量存儲任何類型的變量。
編輯:謝謝你的解釋,它確實有幫助。
什么是a->數據初始化為?
我使用函數初始化數組,並將a->data
初始化為element_size。
調用者必須將resutl轉換為元素*
我以為我可以使用宏來縮短輸入(我認為這是一件壞事嗎?),但我不知道從void*
到struct*
的類型轉換的性能。
直接創建動態數組元素對我來說更實用。
但這不允許我將數組用作通用數組? 我想要的是定義一個可以用來存儲任何類型的通用數組,比如
array *a1 = create_array(sizeof(int)); // array of int
array *a2 = create_array(sizeof(double)); // array of double
etc...
為什么要將數據存儲在連續的塊中?
因為我認為你需要一個連續的內存塊來使用帶偏移量的memcpy。
什么是a->data
初始化為? 為此,在創建(空)數組時應將其設置為NULL。
此外,你解決計算不考慮指針算術。 a->data
是一個指針(對於void *),因此(a->size - 1)*a->element_size
offset將乘以指針的大小(to void *)。 將a->data
設置為void *
應該會導致編譯器錯誤,因為void
沒有大小。
如果你真的想這樣做,最好將a->data
聲明為char *
,保證大小為1。
注意:訪問您的數組將需要轉換為( element*
)。 這將阻止您使用方括號。
您必須提供一個訪問函數,如void * array_at(size_t index) { return &a->data[index*a->element_size]; }
void * array_at(size_t index) { return &a->data[index*a->element_size]; }
然后調用者必須將resutl轉換為element *
。
直接創建一個動態的element
數組似乎對我來說更實用。
如果需要,您仍然可以在其上調用realloc
。
但是我想到的第一個問題是:為什么要將數據存儲在連續的塊中?
這不像你想象的那樣具有內存效率,因為重復調用realloc()
會給內存分配器帶來壓力,浪費時間進行復制,甚至可能使堆碎片甚至超過單個malloc
的集合。
使用void *作為數據數組來評論代碼的最后部分。 代碼應該工作,但它有問題:
您正在傳遞元素指針的地址,而不僅僅是指針本身,它已指向正確(希望)數據。
你也不能在void上做指針算術,但是某些編譯器允許它。
memcpy的正確版本將是
memcpy ( ( unsigned char* )a->data + (a->size - 1)*a->element_size, element, a->element_size);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.