0

在 C中使用有很多缺点void *(内存相关、类型相关、效率方面......)。尽管它们提供了灵活性,但我们还是经常使用它们。

列出使用的缺点/缺点void *(以及 C 中的首选解决方案 - 如果可能)。

编辑: 请通过以下链接: http ://attractivechaos.wordpress.com/2008/10/02/using-void-in-generic-c-programming-may-be-inefficient/

4

6 回答 6

15

void 指针没有效率问题。void 指针的唯一限制是:

  • 出于明显的原因,您不能取消引用 void 指针
  • sizeof(void)是非法的
  • 您不能对 void 指针执行指针算术

然而 GCC 假定它sizeof(void)是 1 并允许对 void 指针进行指针算术 -见这里

于 2008-12-04T08:31:46.400 回答
14

我不同意这个问题的前提。我们在 C 中使用 void* 是因为它是获得多态性的唯一方法。示例:库函数 qsort 和 bsearch。只有一个缺点,那就是基于 void * 的多态是不安全的:一旦你将一个指针强制转换为 void *,没有什么可以阻止你错误地将 void * 强制转换为错误的指针类型。我的学生经常犯这个错误。

可能存在效率成本,因为有时需要分配堆空间才能使用多态数据结构。

任何想了解使用 void * 的多态数据结构的优势和权衡的人都应该得到一份 Dave Hanson 的书C 接口和实现

于 2008-12-04T08:34:13.290 回答
3

呃......我不确定有那么多。当然,你不应该在不必要的void*时候使用。如果您可以使用定义明确的类型,那么就这样做。

以我的经验,void*最适合“匿名”指针(多么令人震惊!),如malloc()'s 返回值,以及仅处理不透明的位缓冲区时。通常,您希望在例如字节级别处理这些缓冲区,然后您unsigned char *当然会使用 .

只是在需要指针的地方随意使用void*就会被破坏、发臭的代码,当然要避免。

于 2008-12-04T08:29:29.180 回答
2

链接到的帖子将操作与指向 C++ 模板操作的 void 指针进行了比较,并得出结论认为模板更有效。这并不奇怪,而且我见过的 C++ 代码很少或从不使用 void 指针。与其他 C++ 工具相比,它通常没有任何优势,并且可能是类型系统中的一个大漏洞。

但是,C 没有 C++ 样式的模板,并且 void 指针是实现必须独立于数据类型的功能所必需的。

因此,当您使用 C 编写并且需要泛型时,空指针是获得它的最有效方法(因为它们是唯一的方法)。当您使用 C++ 编写代码时,几乎所有 void 指针可以完成的事情都有更好的方法,所以不要使用它们。

于 2008-12-04T20:24:47.817 回答
1

您给定的链接部分正确。特别是,当您不处理对象(结构)时,或者通常不处理尚未分配的类型时。使用 int、double 等本机类型和 void-pointers(例如对于容器)几乎总是一件令人讨厌的事情,因为您可以选择将 int(对于 double 这不起作用)转换为指针或您需要为数据类型分配额外的内存。

第一选择很糟糕,因为它不可移植,0 可能不允许作为值,而且感觉很糟糕。第二种选择会浪费内存,并且由于额外的分配确实会(大量)减慢速度。

但是在大多数情况下,您不是在处理本机类型,而是在处理对象,最好是使用指向已经分配的对象的指针,至少我这样做。我从不需要哈希表或整数或双精度映射。仅仅为了指针的类型安全而使用不同的容器实现对我来说是错误的,因为每个实现都会增加你的二进制大小。因此,如果您只需要一个容器来存储指针,那么使用 void-pointers 不会减慢或浪费内存。

但请注意,这都是关于容器实现的,就像你提到的博客文章一样。一般来说,如果不使用 void-pointers,您将无法完成许多事情。

于 2008-12-04T14:46:51.837 回答
1

我不知道,我发现 void 指针对于访问不同的抽象级别 (ABC) 非常有效。作为在不同抽象级别导航相互关联的类的一种方式。它是如此简单,它太棒了。就像 e 的公式或黄金比例一样,应该有一个崇拜虚空*的神秘学*它很棒:)

于 2010-02-21T05:46:21.790 回答