2011-03-31 42 views
2

我写在C的动态数组泛型编程

typedef struct __c_array { 
    void**_elem; 
    int cur_size; 
    int capacity; 
}c_array; 

我的界面是这样的:

extern void push_back_c_array (c_array*, void *); 

现在,用户将不得不为元素分配内存以推进入阵列。有没有什么办法可以避免使用void *。

我想用这个做以下

int a = 5; 
push_back_c_array (<ARRAY_PTR>, a); 

这是可能的。

+0

对typedef结构是有害的。它已经有了一个类型;所做的一切就是通过要求读者引用并记住typedef的基本类型来使更多的代码更复杂。 – 2011-03-31 06:57:25

+0

你能解释一下吗? – Avinash 2011-03-31 06:59:36

+7

我不同意'这是有害的typedef结构',在这种情况下,结构将是一个不透明的句柄,供他的用户使用该数组。 – IanNorton 2011-03-31 07:02:10

回答

2

如果您提供将复制提供的值的push_back_c_array()版本,则可能会这样。为此,您将需要一个额外的参数,指定值的大小:

push_back_c_array(c_array* arr, void* val, unsigned int size); 

你堆了新的价值分配内存,然后做的memcpy。但之后,您需要将其解除分配。因此,您需要记住,哪些值由您分配,哪些值由调用者分配。相当讨厌......所以,如果你这样做 - 永远这样做,并在你的函数的文档中描述这个约定。

+0

谢谢,但从可用性的角度来看,添加大小参数将成为问题。 – Avinash 2011-03-31 07:05:05

+0

根本不是。对于许多C函数来说这是一个常见的情况。 (例如,采用相同的memcpy())。 – weekens 2011-03-31 07:07:10

+0

没有大小,没有calloc! – 2011-03-31 07:08:02

0

您的示例数组包含类型为(void *)的项。它拥有指针。你似乎想要它保持任意类型。在这种情况下,int。你想存储插入数据的副本还是简单地存储调用者给你的指针?

前一段时间,我想要一个简单的数组像行为为我正在写一个游戏,并想出了xrlist。一段时间后,我想存储它们并随机访问它们,所以想出了xrhash

xrlist和xrhash存储用户提供的指针,并期望所有元素是同一类型的(xrhash有一个哈希码和比较的回调函数)

0

你可能会得到更好的服务分配的内存一小块(或许举行工会),并推回元素,直到你填补它。然后重新分配,或分配一个两倍大小的数组并复制所有内容。

0

你的例子whit a = 5应该工作,只要你将使用整数或任何其他类型的大小与int相同。通用数组的用户将需要推动结构,就像你一样。但是,大元素不能/不应该被值传递,但它的指针应该被传递。

使用泛型和没有被限制在sizeof(int)带来一些额外的努力从用户。我认为最好的解决方案是你在函数中传递分配的指针(void *),并且任何想要取出这个元素的人都应该释放()这个结构体。

+0

我同意你关于大型结构,这样的指导方针可以发布,但对于像int这样的小型数据类型,要求用户每次分配真的很不方便。 – Avinash 2011-03-31 07:46:16