Проблема при приведении в C - PullRequest
2 голосов
/ 07 декабря 2010

У меня есть следующая структура данных в C:

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

Я определил sharedMemoryBuffer, который будет содержать массив структур SharedMemory:

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

Моя проблема сейчас заключается в попытке прочитать из общей памяти блок в данной позиции. Я думал, что следующего должно быть достаточно, но компилятор C жалуется:

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

Ошибка:

Invalid use of void expression.

Как мне привести последнюю строку кода так, чтобы компилятор не кричал на меня об этой строке?

Спасибо

Ответы [ 5 ]

4 голосов
/ 07 декабря 2010

sharedMemoryBuffer->buffer относится к типу void *. Это означает, что вы не знаете, на какой тип он указывает, поэтому вы не можете разыменовать его (с помощью * или []).

Если на самом деле вы хотите разыграть buffer, вы должны посмотреть:

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

или, более вероятно:

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

поскольку вы пытаетесь получить указатель на нужный элемент массива.

4 голосов
/ 07 декабря 2010

Проблема здесь заключается в приоритете операторов: оператор индекса ([]) имеет более высокий приоритет, чем приведение, поэтому он пытается взять индекс void * и привести его к Block * вместо преобразования *От 1004 * до Block * и , затем , индексируя его.Используйте круглые скобки:

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

или (как я предпочитаю с арифметикой указателей):

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

или, если вы по какой-то причине хотите скопировать Block в переменную стека:

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

РЕДАКТИРОВАТЬ: исправлена ​​ошибка.Мой код выдал Block вместо Block *, когда требовался OP.

2 голосов
/ 07 декабря 2010

давайте разберем его, заключив в скобки, как его видит компилятор

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

Там вы заметите, что вы преобразуетесь в Block * после использования индексов для разыменования пустого указателя это означает, что вы пытаетесь разыграть void до Block*

Что вы, вероятно, хотите сделать:

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

, который укажет вас на readPosition-й блок вбуфер

2 голосов
/ 07 декабря 2010

Буфер является пустым указателем. Вы не можете индексировать в пустой указатель.

unsigned char может работать лучше, поскольку он определяется как один байт.

1 голос
/ 07 декабря 2010

Нельзя ссылаться на пустой указатель. Вам нужно привести пустой указатель к char *, затем добавить в него положение чтения и затем вернуть обратно Block *.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...