问题标签 [void-pointers]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
11399 浏览

c++ - void 指针:C 和 C++ 之间的区别

我试图了解 C 和 C++ 在 void 指针方面的区别。以下在 C 中编译,但不是在 C++ 中编译(所有编译都使用 gcc/g++ -ansi -pedantic -Wall 完成):

因为mallocreturn void*,C++ 不允许分配给它,int*而 C 确实允许。

但是,这里:

C++ 和 C 都可以毫无怨言地编译它。为什么?

K&R2 说:

任何指向对象的指针都可以转换为类型void *而不会丢失信息。如果将结果转换回原始指针类型,则恢复原始指针。

这很好地总结了void*C 中的所有转换。C++ 标准规定了什么?

0 投票
7 回答
31756 浏览

c - 在 C 中传递 Void 类型参数

您好,我正在使用 C 语言进行分配,我需要将未知类型的参数传递给函数。

例如,假设我有以下内容:

可变元素为 void 的原因是因为有 3 种可能性。然而,所有 3 个都有一个名为“Count”的成员变量。

当我尝试编译我在 Eclipese 中编写的实际代码时,我收到以下错误:

错误:请求成员“计数”不是结构或联合

我猜这是因为编译器事先不知道“元素”的类型。但是我不明白为什么这不起作用。

感谢帮助!

0 投票
3 回答
6929 浏览

c++ - 通过 void* 进行投射,而不是使用 reinterpret_cast

我正在读一本书,我发现reinterpret_cast不应该直接使用它,而是将其转换为 void* 并结合static_cast

代替:

但是,我找不到解释为什么这比直接演员更好。如果有人能给我一个解释或指出我的答案,我将不胜感激。

提前致谢

ps 我知道是干什么reinterpret_cast用的,但我从来没见过这样用的

0 投票
8 回答
9548 浏览

c - void 大小未知时的指针运算

在 Visual Studio C++ 版本 9(可能还有其他版本)中,以下代码:

生成这些 错误

此代码在 GCC 下工作,GCC 将其sizeof(void)视为1.

有没有办法绕过这个限制,因为char *为了指针算术的目的而显式地强制转换会增加混乱(void *被很好地识别并用作指向原始内存的无类型指针)。

更新0

  • 请注意,我很清楚该标准的存在。
  • 想做原始指针算术。
  • 我要sizeof(void)表明我很清楚这不是1问题的原因。
  • 该代码示例只是为了演示生成错误所需的内容。
  • 我知道这不是一种“正常”的使用方式void,但这是 C,并且会发生这些事情。
  • 是的,人们需要在底层做这件事。我不是在追求为什么,我在追求如何。如果你想知道为什么,看看一些内核源代码,或者你友好的 glibc。

更新1

这个问题似乎引起了很大的混乱。问题不在于为什么拥有sizeof(void) == 1不标准,而在于如果不是标准该怎么办。

在要进行单字节指针运算的情况下,事实证明强制转换为char *是正确的答案,不是因为*(void *)没有大小,而是因为标准实际上保证*(char *)是 always 1。因此,对于原始指针算术的目的,使用char *总是正确的,并且与 GCC 扩展一致。void *

为了进一步强调这一点,void *对于指向无类型内存的指针是正确的选择,并且对于原始指针算术char *来说是正确的类型。

0 投票
7 回答
3653 浏览

c - 当 sizeof(char) != 1 时 C 中的字节精度指针算术

如何以单字节精度便携地执行指针运算?

请记住:

  • char在所有平台上都不是 1 字节
  • sizeof(void) == 1仅在 GCC 中作为扩展提供
  • 虽然某些平台可能有指针 deref 指针对齐限制,但算术可能仍需要比最小基本 POD 类型的大小更精细的粒度
0 投票
2 回答
1820 浏览

python - 构造可从 C 调用的python函数,输入参数具有*输出*语义

用例如下:

  • 给定一个用 C 实现的(固定的,不可更改的)DLL
  • 需要:在 python 中实现的这个 DLL 的包装器(选择的方法:ctypes)

DLL 中的一些函数需要同步原语。为了获得最大的灵活性,DLL 的设计者完全依赖于客户端提供的回调。更准确地说,该 DLL 应具有:

  • 用于创建同步对象的回调函数
  • 获取/释放同步对象锁定的回调函数
  • 和一个用于销毁同步对象的回调函数

因为从DLL的角度来看,同步对象是不透明的,它会被一个void *实体所代表。例如,如果其中一个 DLL 函数想要获取锁,它应该这样做:

可以看出,回调create_mutex输入参数具有输出语义。这是通过void **签名实现的。

这个回调(和其他三个)必须在 python 中实现。我失败了 :-) 为简单起见,让我们只关注创建回调,也为简单起见,让不透明对象为int.

模拟回调使用的玩具 DLL 如下 (ct_test.c):

想要提供回调并使用 DLL 的 python 代码如下:

当使用 in-DLL 提供的回调(通过设置set_c_callback())时,这可以按预期工作:

但是,在另一种情况下 - 使用 python 回调 - 失败:

我哪里错了?

0 投票
11 回答
6680 浏览

c - 泛型与类型安全?在 C 中使用 void*

我来自 OO(C#、Java、Scala),我非常重视代码重用和类型安全的原则。上述语言中的类型参数完成了这项工作,并启用了类型安全且不会“浪费”代码的通用数据结构。

当我陷入 C 中时,我意识到我必须做出妥协,我希望它是正确的。要么我的数据结构void *在每个节点/元素中都有一个并且我失去了类型安全性,要么我必须为我想要使用它们的每种类型重新编写我的结构和代码。

代码的复杂性是一个明显的因素:遍历数组或链表是微不足道的,向*next结构添加 a 也不是额外的努力;在这些情况下,不要尝试和重用结构和代码是有意义的。但对于更复杂的结构,答案并不那么明显。

还有模块化和可测试性:将类型及其操作从使用该结构的代码中分离出来,使测试变得更容易。反之亦然:在一个结构上测试一些代码的迭代,同时它试图做其他事情会变得混乱。

那么你的建议是什么?void *和重用或类型安全和重复的代码?有什么一般原则吗?当它不适合时,我是否试图强制 OO 进入程序?

编辑:请不要推荐 C++,我的问题是关于 C 的!

0 投票
7 回答
1462 浏览

c++ - 从 void 指针缓冲区进行结构实例化

这是一些对我来说看起来很有趣的 C++ 代码,但我知道它有效。

定义了一个结构,在程序中我们使用 void 指针分配内存。然后使用分配的缓冲区创建结构。

这是一些代码

代码有更多的东西,但这就是它的要点。

我没有测试过这段代码,但我正在查看的代码已经过很好的测试,并且可以正常工作。但是怎么做?

谢谢。

编辑:修复了内存泄漏。

0 投票
7 回答
526 浏览

c - 将整数值转换为 void* 是回调中常用的范例吗?

不是将实际指针发送到一个值,而是将该值强制转换为一个指针。我在 GTK 程序的 GUI 界面代码中找到了这些示例。

在上面的例子中,我指的是g_signal_connect. 当on_paste_button_pressed被 GTK2 调用时,on_paste_button_presseduser_datavoid 指针转换回来,如下所示:

实际上,我在代码中添加了这个特定的示例,但我基于已经存在的内容。我添加了位移以避免有关投射的警告。该程序本身有四个窗格,其中包含相当多的小部件,复制和粘贴按钮允许您将所有值从一个窗格复制到另一个窗格。

这种将值转换为指针地址的方法是否经常使用,是否有不应该使用的原因?

编辑:

从整数到空指针的转换也可以像这样实现:

0 投票
4 回答
1106 浏览

c++ - C++:强制转换为 void* 并返回

* ---编辑 - 现在是整个源*

当我最后调试它时,“get”和“value”有不同的值!可能,我转换为 void* 并以错误的方式返回给用户?

解决方案

创建一种“序列化器”,它将所有 POD 转换为 void*,然后将这些部分合并

PS 或者我希望将 User 重写为 POD 类型,一切都会好起来的。

添加

这很奇怪,但是......我将一个明确的非 pod 对象投射到 void* 并返回(它里面有 std::string)并且没关系(没有将它发送到数据库并返回)。怎么会这样?在我投递并发送“槽”db 后,明确地发送 pod 对象(没有额外的方法,所有成员都是 pod,它是一个简单的 struct {int a; int b; ...})我回来弄脏了一个。我的方法有什么问题?

在第一次“添加”后大约一周添加

该死的...我已经编译了它,只是为了看看它返回哪种污垢,哦!没关系!...我不能!... 啊!.. 上帝... 一个合理的问题(在 99.999% 的情况下,正确答案是“我的”,但是...这里...) - 这是谁的错?我的还是VS的?