devoured elysium
devoured elysium

Reputation: 105227

Problem when casting in C

I have the following data structure in C:

typedef struct {
    void* buffer;
        ...
} SharedMemory;

I have defined a sharedMemoryBuffer that will contain an array of SharedMemory structs:

sharedMemoryBuffer = createSharedMemory("/xxxyz", NUM_BLOCKS * sizeof(Block));

my problem is now in trying to read from the shared memory a block in a given position. I thought the following should be enough, but the C compiler is complaining:

Block* block = (Block*)sharedMemoryBuffer->buffer[readPosition];

The error is:

Invalid use of void expression.

How should I cast the last line of code such that the compiler doesn't yell at me about that line?

Thanks

Upvotes: 2

Views: 253

Answers (5)

Chris Lutz
Chris Lutz

Reputation: 75479

The problem here is operator precedence: the index operator ([]) has higher precedence than the cast, so it tries to take the index of a void * and cast it to a Block * rather than casting the void * to a Block * and then indexing it. Use parenthesis:

Block *block = &((Block *)sharedMemoryBuffer->buffer)[readPosition];

or (the way I prefer with pointer arithmetic):

Block *block = (Block *)sharedMemoryBuffer->buffer + readPosition;

or, if you wanted to copy the Block to a stack variable for some reason:

Block block = ((Block *)sharedMemoryBuffer->buffer)[readPosition];

EDIT: corrected an error. My code produced a Block instead of a Block * as the OP needed.

Upvotes: 4

paxdiablo
paxdiablo

Reputation: 882776

sharedMemoryBuffer->buffer is of type void *. That means you do not know what type it points to, so you can't dereference it (with either * or []).

If it's actually the buffer you want to cast, you should look into:

Block* block = ((Block*)(sharedMemoryBuffer->buffer))[readPosition];

or, more likely:

Block* block = &(((Block*)(sharedMemoryBuffer->buffer))[readPosition]);

since you're trying to get a pointer to the desired array element.

Upvotes: 4

tobyodavies
tobyodavies

Reputation: 28119

lets break it down by parenthesizing it as the compiler sees it

Block* block = (Block*)(sharedMemoryBuffer->buffer[readPosition]);

You'll notice there that you are casting to Block* after using subscripts to dereference a void pointer which means you are trying to cast a void to Block*

What you probably want to do is:

Block* block = ((Block*)(sharedMemoryBuffer->buffer))+readPosition;

which will point you at the readPositionth Block in the buffer

Upvotes: 2

leiz
leiz

Reputation: 4052

You can not deference a void pointer. You need to cast void pointer to char* then add readposition to it and then cast back to Block*.

Upvotes: 1

Jonathan Sternberg
Jonathan Sternberg

Reputation: 6677

Buffer is a void pointer. You can't index into a void pointer.

unsigned char might work better since that's defined as a single byte.

Upvotes: 2

Related Questions