【发布时间】:2014-01-24 07:29:46
【问题描述】:
所以学习 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。
调用者必须将结果转换为元素 *
我认为我可以使用宏来缩短打字时间(我认为这是一件坏事?),但我不知道从 void* 到 struct* 的类型转换性能。
对我来说,直接创建元素的动态数组似乎更实用。
但这不允许我将数组用作通用数组?我想要的是定义一个通用数组,我可以用它来存储任何类型,比如
array *a1 = create_array(sizeof(int)); // array of int
array *a2 = create_array(sizeof(double)); // array of double
etc...
为什么要将数据存储在一个连续的块中?
因为我认为您需要一个连续的内存块才能使用带有偏移量的 memcpy。
【问题讨论】:
标签: c pointers void-pointers pointer-arithmetic