问题标签 [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.
c - C 中指向 void 指针的指针 - 我可以将 void** 用于基本多态性吗?
我可以理解 avoid**
可能在内存中的样子,但我想知道我是否正确使用它。我在下面描述的内容是否存在任何基本缺陷?例如,虽然我可以说“它对我有用”,但我是否以某种方式创建了糟糕/不可移植的代码?
所以我有一个小行星克隆。可以发射子弹的实体有 3 个,玩家 ( SHIP *player_1
, SHIP *player_2
) 和 UFO ( UFO *ufo
)。当子弹发射时,知道是谁发射的子弹很重要;如果是玩家,当它击中某些东西时,他们的分数需要增加。所以,子弹将存储它属于什么类型的实体 ( owner_type
) 以及直接指向所有者 ( owner
) 的指针:
然后,当玩家按下按钮或 UFO 看到目标时,将调用以下函数之一:
...它们可能被称为,例如,像这样:
最后,当子弹击中目标(例如小行星)时,我们取消对所有者的引用。如果它是一艘船,我们可以在那里增加分数。
这似乎是一个合理的方法吗?就像我说的,它对我有用,但我只有几个月的 C 经验。
最后一点:为什么我不使用 avoid*
而不是 a void**
?因为我想避免悬空指针。换句话说,假设它player_1
死了并且被释放了,但他们的子弹继续前进并击中了一颗小行星。如果我只有一个void*
,则该hit_asteroid
函数无法知道bullet->owner
指向已取消分配的内存。但是使用 a void**
,我可以有效地检查它是否为 NULL;如果player_1
是 NULL,那么*bullet->owner
也将是 NULL。
编辑:到目前为止,所有受访者都同意在这里使用 void** 可能不是必需的,因为我可以避免悬空指针问题(例如,仅通过静态分配基础对象)。他们是正确的,我会重构。但是我仍然有点想知道我是否以某种方式使用了 void** 可能会破坏某些东西,例如在内存分配/强制转换方面。但我想如果没有人举手宣布它有故障,它至少类似于技术上可行的东西。
谢谢!
c++ - Ncurses 用户指针
我正在尝试学习 ncurses,并且正在阅读此处的精彩指南,但用户指针处的示例无法编译。尝试编译时出现此错误。
menu.cpp: In function 'int main()':
menu.cpp:44: error: invalid conversion from 'void (*)(char*)' to 'void*'
menu.cpp:44: error: initializing argument 2 of 'int set_item_userptr(ITEM*, void*)'
menu.cpp:70: error: invalid conversion from 'void*' to 'void (*)(char*)'
此外,您可能需要添加 cstdlib 和 cstring 才能使用 strlen 和 calloc 进行编译。
我对 void 指针了解不多,因此非常感谢您对修复示例的帮助。
谢谢
c - GLib 原子和内存块
以下代码片段来自The Official GNOME 2 Developer's Guide:
这是否意味着每个原子都是 42 字节,每个“内存块”包含
4216 个原子,并且40000/16=2500
在运行上述代码时会创建内存块?他们为什么在这里使用 gchar* ?运行时是否会发生从 gpointer (void*) 到 gchar* 的隐式转换
data[i] = g_mem_chunk_alloc(my_chunk);
?如果上述陈述为真,则每个 gchar* 指向 42 字节的内存。那么如何访问特定原子的所有字节呢?会
data[7]+41
是一个可用的内存位置吗?
当我尝试编译代码 gcc 产生此错误消息:
error: storage size of ‘my_chunk’ isn’t known
怎么了?
c++ - 多重继承:从 void * 转换为第二个基类后的意外结果
我的程序需要使用 void* 在动态调用情况下传输数据或对象,以便它可以引用任意类型的数据,甚至是原始类型的数据。但是,我最近发现,在具有多个基类的类的情况下,向下转换这些 void* 的过程会失败,甚至在对这些向下转换的指针调用方法后使我的程序崩溃,即使内存地址似乎是正确的。崩溃发生在访问“vtable”期间。
所以我创建了一个小测试用例,环境是 Mac OS X 上的 gcc 4.2:
产生以下输出:
如您所见,“装饰(每个 void*)”结果是完全错误的。它也应该是 30,30,就像第一行一样。
无论我在 shape_cast() 中使用什么铸造方法,我总是会为 Decorated 部分获得相同的意外结果。这些 void *.
根据我对 C++ 的理解,这应该是可行的。有没有机会让它与 void* 一起工作?这可能是 gcc 中的错误吗?
谢谢
c - 关于我在 C 中使用 void* 作为动态数据类型的模块化代码的几个问题
几天前我发布了这个问题,每个人都建议我使用void*
,我做到了。我认为他们中的一些人还指出了一些我需要注意的事情,但我不确定它们到底是什么。但是,我遇到了一些问题......
我不会将我所有的代码都发布在它很大的地方,相反,我会发布我认为重要的东西,希望足以让你帮助我。
我的哈希表结构是这样的:
我的插入函数的签名是这样的:
在该函数内部的某个地方,当我在哈希表中找到一个空闲存储桶时,我会这样做:
所有这些都带来了一些问题:
1)正如您在上面看到的,我只是将空闲存储桶的每个键/值对设置为与键/值hashInsert
函数参数传递的相同指针。这带来了一个问题,您可能已经注意到了......例如,做这样的事情:
如果输入是“KeyA”,然后是“KeyB”,则两者都将“KeyB”作为存储桶键。同样的事情适用于值而不仅仅是键,因为它们基本上是相同的类型,因为我想让我的代码完全模块化,适用于任何数据类型。
我怎么能解决这个问题?
我的第一个想法是使用strdup(str)
并将其传递给hashInsert
函数。那将解决问题。由于这是在主代码中处理的,因此我也可以轻松地将malloc()
其用于需要作为值传递的任何其他数据类型(键可能始终是字符串或 int)。
但是这个解决方案带来了另一个问题......
2)我应该如何释放这个分配的内存?当然,它是由“主程序员”而不是“哈希表模块程序员”分配的,所以“主程序员”应该在主代码中释放它,对吧?但是,对我来说,这看起来不像模块化代码。
我的代码还有一个hashDestroy
功能,可以释放所有分配的内存。但是我怎样才能使用这个功能来释放一切呢?我不能只遍历每个键/值并free()
在它们上使用,因为它们中的一些可能一开始就不是malloc'd
任何程序员的,我不需要释放它们。
我怎样才能知道哪些是我hashDestroy
必须免费的,哪些不应该?
3)最后,我想我也可以把这个问题混在一起......在第一点,我的建议是使用strdup()
或malloc
“修复”那个特定问题(同时引入另一个问题),但这看起来也不是很模块化大部头书。这种内存分配应该在哈希表模块代码中完成,而不是由“主程序员”在主代码中完成。
你建议我如何解决这个问题?我的意思是,数据类型可以是任何东西,虽然使用strdup()
有很大帮助,但它只适用于字符串。如果我需要为某些特定结构或只是一个 int 分配内存怎么办?
很抱歉这篇大文章,但我认为这些问题都是相关的,我需要一些帮助来弄清楚它们,因为我的 C 知识并不是那么极端。我最近才知道void*
所以...
com - 使用 ATL 和 IUnknownPtr 时正确的转换方法是什么?
在修改现有 ATL COM 对象的过程中,我看到了一篇来自“The Old New Thing”博客的文章,名为“人们搞砸 IUnknown::QueryInterface 的方式”,评论部分开始讨论其中一个受访者 (Norman Diamond) 指出,在文章的一个示例中,强制转换为 void** 是不正确的。
但是,当我尝试纠正我的代码以正确进行转换时,我最终会出现内存泄漏。
示例如下:
诺曼说
朋克不是虚无*。朋克是一个未知数*。
void** 不是通用指针类型。void* 是一种通用指针类型,并且 char* 和亲戚以这种方式被视为等价,但 void** 不是。
如果你想遵守调用约定并避免可怕的死亡,你必须这样做:IUnknown *punk; 无效*朋克无效;psf->QueryInterface(IID_IUnknown, &punkvoid); 朋克 = (IUnknown *)punkvoid;
许多其他 MSDN 贡献者犯了同样的错误……有些人可能会说它在迄今为止的所有 VC++ 实现中都有效,但这并不能使它成为正确的代码,而且它仍然违反了调用约定。
鉴于此,我去更改我的旧代码 - 如下:
然后我将其更改如下:
但是现在我的应用程序有一个来自 COM 对象的内存泄漏
c++ - 等效于 C++ 的 window.setTimeout()
在 javascript 中有这个甜蜜的函数window.setTimeout( func, 1000 ) ;
,它将在 1000 毫秒后异步调用。func
我想在 C++ 中做类似的事情(没有多线程),所以我把一个示例循环放在一起:
我怎样才能使这样的工作?
c - 使用 void 指针作为函数参数的问题
看不懂这个结果。。。
编码:
我打这个电话:bar(900011009);
但printf()
输出是:
我真的需要key
成为一个空指针,我该如何解决这个问题?
c - C:从 void 指针推断类型
假设一个函数将 void 指针作为参数,如下所示:int func(void *p);
我们如何确定或猜测 p 指向的类型?
c++ - C++中的空指针
我写了这个qsort:
当我打电话时
它说从 char** 到 void** 的无效转换。为什么这是错误的?
这是代码: