在C中使用void *
有许多缺点(内存相关,类型相关,效率明智......)。尽管如此,我们还是大量使用它们来提供灵活性。
使用void *
列出缺点/缺点(如果可能,请列出C中的首选解决方案)。
修改 请仔细阅读以下链接: http://attractivechaos.wordpress.com/2008/10/02/using-void-in-generic-c-programming-may-be-inefficient/
答案 0 :(得分:14)
void指针没有效率问题。 void指针的唯一限制是:
sizeof(void)
是非法的然而,GCC假设sizeof(void)
为1并允许指针算术在void指针上 - see here
答案 1 :(得分:14)
我不同意这个问题的前提。我们在C中使用void *,因为它是获得多态的唯一方法。示例:库函数qsort和bsearch。只有一个缺点,即基于void *的多态性是不安全的:一旦你将指针强制转换为void *,就没有什么能阻止你将void *转换为错误的指针类型错误。我的学生经常犯这个错误。
可能存在效率成本,因为有时需要分配堆空间以使用多态数据结构。
任何想要看到使用void *的多态数据结构的优点和权衡的人都应该得到Dave Hanson的书C Interfaces and Implementations
的副本答案 2 :(得分:3)
void*
。如果您可以使用明确定义的类型,那么就这样做。
根据我的经验,void*
最适合“匿名”指针(多么令人震惊!),如malloc()
的返回值,以及处理不透明的位缓冲区时。通常情况下,您希望在例如:字节级别,然后你当然会使用unsigned char *
。
只需随意使用void*
,只要你需要一个指针,就会破坏,发臭的代码,当然要避免使用。
答案 3 :(得分:2)
链接到帖子将操作与使用C ++模板的操作的void指针进行比较,并得出结论模板更有效。这并不奇怪,我见过的C ++代码很少或从不使用void指针。它通常没有其他C ++工具提供优势,并且可能是类型系统中的一个漏洞。
但是,C没有C ++样式的模板,并且void指针是实现必须独立于数据类型的功能所必需的。
因此,当你用C语言编写,并且需要通用性时,void指针是获得它的最有效方法(因为它们是唯一的手段)。当你用C ++编写时,有更好的方法可以完成虚拟指针可以完成的任何操作,所以不要使用它们。
答案 4 :(得分:1)
您的指定链接部分属实。特别是,当您不处理对象(结构)时,或者通常使用尚未分配的类型时。使用像int,double等原生类型和void指针(例如对于容器)几乎总是一个蠢事,因为你可以选择将int(对于一个double,这不起作用)转换为指针或你需要为数据类型分配额外的内存。
首选是不好的,因为它不可移植,0可能不允许作为一个值,它只是感觉不好。第二种选择会浪费内存,而且由于额外的分配,确实会导致(大规模)减速。
但是在大多数情况下你不是在处理本机类型,而是使用对象,最好用指向已分配的对象的指针来表示,至少我这样做。我从来不需要哈希表或整数或双打的地图。并且对于指针的类型安全性而言,使用不同的容器实现对我来说是错误的,因为每个实现都会增加二进制大小。因此,如果您只需要一个容器来存储指针,那么使用void指针就不会减慢或浪费内存。
但是请注意,这完全是关于容器实现的,就像你提到的博客文章一样。一般来说,如果不使用void-pointers,你就无法完成许多事情。
答案 5 :(得分:1)
我不知道,我发现无效指针对于访问不同级别的抽象(ABCs)非常有效。作为在不同抽象层次上导航相互关联的类的一种手段。它如此简单,令人敬畏。就像e或黄金比例的公式一样,应该有一个崇拜虚空的神秘事物*那个伟大的:)