我可以理解void**在记忆中看起来如何,但我想知道我是否正确使用它.我在下面描述的是否有任何根本缺陷?例如,虽然我可以说"它对我有用",但我是否以某种方式创建了错误/不可移植的代码?
所以我有一个小行星克隆.有三个实体可以发射子弹,即玩家(SHIP *player_1,SHIP *player_2)和UFO(UFO *ufo).当子弹被射击时,重要的是要知道谁射了子弹; 如果它是一名球员,当它击中某些东西时,他们的分数需要增加.因此,子弹将存储它所属的实体类型(owner_type)以及直接指向所有者(owner)的指针:
enum ShipType
{
SHIP_PLAYER,
SHIP_UFO
};
typedef struct Bullet
{
// ...other properties
enum ShipType owner_type;
void **owner;
} BULLET;
Run Code Online (Sandbox Code Playgroud)
然后,当玩家点击按钮或UFO看到目标时,将调用以下功能之一:
void ship_fire(SHIP **shipp)
{
BULLET *bullet = calloc(1, sizeof(BULLET));
bullet->owner_type = SHIP_PLAYER;
bullet->owner = (void**)shipp;
// do other things
}
void ufo_fire(UFO **ufop)
{
BULLET *bullet = calloc(1, sizeof(BULLET));
bullet->owner_type = SHIP_UFO;
bullet->owner = (void**)ufop;
// do other things
}
Run Code Online (Sandbox Code Playgroud)
......他们可能被称为,例如,像这样: …
Error 1 error C2036: 'const void *' : unknown size file.cpp 111
Run Code Online (Sandbox Code Playgroud)
我不跟随.GCC从不抱怨void*指针算法,即使是-ansi -pedantic -Wall.有什么问题?
这是代码 -
struct MyStruct {
const void *buf; // Pointer to buffer
const void *bufpos; // Pointer to current position in buffer
};
...
size_t someSize_t, anotherSize_t;
MyStruct *myStruct = (MyStruct *) userdata;
...
if ( (myStruct->bufpos + someSize_t) >
(myStruct->buf + anotherSize_t) ) { // Error on this line
...
Run Code Online (Sandbox Code Playgroud) 我在C++中有一个数组:
Player ** playerArray;
Run Code Online (Sandbox Code Playgroud)
它在它所在的类的构造函数中初始化.
在析构函数中,我有:
delete playerArray;
Run Code Online (Sandbox Code Playgroud)
除了通过Valgrind测试程序时,它说有一些调用要删除一个void指针:
operator delete(void*)
Run Code Online (Sandbox Code Playgroud)
我想在调用delete之前测试playerArray是否为void指针以避免此错误.
有谁知道如何做到这一点?
我需要访问一个缓冲区中的对象,由void指针指向.该对象位于某个偏移量,但由于禁止对void指针进行算术运算,因此如何访问该对象?
假设我有这个函数,它是一些gui工具包的一部分:
typedef struct _My_Struct My_Struct;
/* struct ... */
void paint_handler( void* data )
{
if ( IS_MY_STRUCT(data) ) /* <-- can I do something like this? */
{
My_Struct* str = (My_Struct*) data;
}
}
/* in main() */
My_Struct s;
signal_connect( SIGNAL_PAINT, &paint_handler, (void*) &s ); /* sent s as a void* */
Run Code Online (Sandbox Code Playgroud)
由于paint_handler也将由GUI工具包的主循环与其他参数一起调用,因此我不能总是确定我接收的参数将始终是指针s.
我可以IS_MY_STRUCT在paint_handler函数中执行某些操作来检查我收到的参数是否可以安全地返回到My_Struct*?
我正在为一个简单的,类似Lisp的编程语言编写一个解释器.它将代码处理成节点,所有节点都有类型,其中一些可能具有索引顺序的子节点.由于信息性质的不同,我不能对所有节点值使用相同长度的类型.它们的类型名称是枚举类型,但我对值类型的唯一想法是void *.但是当我使用它时,我认为我必须非常小心.我的意思是,我不能使用任何默认的析构函数,我必须编写一个关心节点类型的析构函数.此外,我甚至需要使用大量的强制转换来访问值.
这就是我所说的:
enum NodeType {/* Some node types */}
class Node
{
public:
Node(string input_code);
private:
NodeType type; // Having this I can know the type of value
void* value;
};
Run Code Online (Sandbox Code Playgroud)
有没有更安全的方法,制作更好的代码,但仍然像使用void指针一样高效?
为什么说我们可以在C编程中用void*实现参数多态?这是不正确的?
教授提出了这个问题而从未回答过.我认为void*实际上是一个非常低级别的被认为是参数多态的东西但是有更强的理由吗?
我需要将int(指定一个字节偏移量)强制转换为const void*。真正适合我的唯一解决方案是c样式强制转换:
int offset = 6*sizeof(GLfloat);
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,0,(void*)offset);
Run Code Online (Sandbox Code Playgroud)
我想摆脱c风格的转换,但找不到有效的解决方案。我试过了
static_cast<void*>(&offset)
Run Code Online (Sandbox Code Playgroud)
并进行编译,但这不是正确的解决方案(此方法的整体输出有所不同)。正确的解决方案是什么?
链接至的文档glVertexAttribPointer:链接
我需要通用的方法来检查void*是否包含0到num_bytes.我提出了以下方法.*p每次都不包含相同类型的数据因此无法做到*(type*)p
bool is_pointer_0(void *p, int num) {
void *cmp;
cmp = (void*)malloc(num);
memset(cmp, 0, num);
if (memcmp(p, cmp, num)) {
free(cmp);
return false;
} else {
free(cmp);
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
该函数在每次调用时分配和释放num个字节,我认为不是很好.请建议更快的方法.感谢帮助.
更新:
这种方法怎么样?
bool is_pointer_0(void *p, int num) {
void *a = NULL;
memcpy(&a, p, num);
return a == NULL;
}
Run Code Online (Sandbox Code Playgroud) 我正在使用visual studio进行C项目.我试着编译以下代码:
void shuffle(void *arr, size_t n, size_t size)
{
....
memcpy(arr+(i*size), swp, size);
....
}
Run Code Online (Sandbox Code Playgroud)
我在Visual Studio Compiler中遇到以下错误:
error C2036: 'void *' : unknown size
Run Code Online (Sandbox Code Playgroud)
该代码与GCC编译良好.如何解决这个错误?
void-pointers ×10
c ×5
c++ ×5
pointers ×4
casting ×2
void ×2
interpreter ×1
memory ×1
opengl ×1
valgrind ×1
visual-c++ ×1
windows ×1