我在C中有以下数据结构:
typedef struct {
void* buffer;
...
} SharedMemory;
我已经定义了一个包含SharedMemory结构数组的sharedMemoryBuffer:
sharedMemoryBuffer = createSharedMemory("/xxxyz", NUM_BLOCKS * sizeof(Block));
我现在的问题是尝试从共享内存中读取给定位置的块。我认为以下内容应该足够了,但C编译器抱怨:
Block* block = (Block*)sharedMemoryBuffer->buffer[readPosition];
错误是:
Invalid use of void expression.
我应该如何转换最后一行代码,以便编译器不会对我大喊那条线?
由于
答案 0 :(得分:4)
这里的问题是运算符优先级:索引运算符([]
)的优先级高于强制转换,因此它尝试获取void *
的索引并将其转换为Block *
而不是将void *
转换为Block *
和然后索引它。使用括号:
Block *block = &((Block *)sharedMemoryBuffer->buffer)[readPosition];
或(我更倾向于使用指针算法):
Block *block = (Block *)sharedMemoryBuffer->buffer + readPosition;
或者,如果您想出于某种原因将Block
复制到堆栈变量:
Block block = ((Block *)sharedMemoryBuffer->buffer)[readPosition];
编辑:纠正错误。我的代码产生了Block
,而不是OP所需的Block *
。
答案 1 :(得分:4)
sharedMemoryBuffer->buffer
的类型为void *
。这意味着您不知道它指向哪种类型,因此您无法取消引用它(使用*
或[]
)。
如果它实际上是您要投射的buffer
,您应该查看:
Block* block = ((Block*)(sharedMemoryBuffer->buffer))[readPosition];
或更可能:
Block* block = &(((Block*)(sharedMemoryBuffer->buffer))[readPosition]);
因为您正在尝试将指针添加到所需的数组元素中。
答案 2 :(得分:2)
Buffer是一个void指针。您无法索引到空指针。
unsigned char可能效果更好,因为它被定义为单个字节。
答案 3 :(得分:2)
让我们在编译器看到它时将其括起来将其分解
Block* block = (Block*)(sharedMemoryBuffer->buffer[readPosition]);
您会注意到在使用下标取消引用空指针之后,您正在转换为Block * ,这意味着您正在尝试将 您可能想要做的是: 将指向缓冲区中的void
转换为Block*
< / p>
Block* block = ((Block*)(sharedMemoryBuffer->buffer))+readPosition;
readPosition
块
答案 4 :(得分:1)
您无法取消引用void指针。您需要将void指针转换为char *,然后向其添加readposition,然后转换回Block *。