Выражение должно иметь тип указатель на структуру или объединение? - PullRequest
1 голос
/ 16 октября 2019

Работа со связанным списком для извлечения данных из заголовка списка. Данные уже установлены в Главе, но когда я пытаюсь получить к ним доступ, я получаю эту ошибку. Думаю, есть проблема с указателями, но я не могу решить ее.

int main(int argc, char **argv)
{
    int i;

    struct timeval start, end;
    struct element *Head = NULL;
    struct element *Tail = NULL;

    //creating job queue
    for (i = 0; i < NUMBER_OF_JOBS; i++) {
        addLast(generateProcess(), &Head, &Tail);
    }

    //go through job queue running processes and removing processes
    while (Head) {
        runPreemptiveJob(Head->pData, &start, &end);

        int responseTime = getDifferenceInMilliSeconds(Head->pData->oTimeCreated, start);

        printf("Response Time is: %d\n", responseTime);

        Head = Head->pNext;
    }
}

Я ожидаю, что смогу использовать данные в oTimeCreated, получив к ним доступ через элемент head, который имеет структуру в своем поле данных.

Ошибка при вызовеФункция getDifferenceInMilliSeconds: я получаю сообщение об ошибке в заголовке, которое говорит: «Выражение должно иметь тип указатель на структуру или объединение.

Элемент показан здесь:

struct element
{
    void * pData;
    struct element * pNext;
};

generateProcess ()возвращает процесс struct, как определено ниже:

struct process
{
    int iProcessId;
    struct timeval oTimeCreated;
    struct timeval oMostRecentTime; 
    int iInitialBurstTime;
    int iPreviousBurstTime;
    int iRemainingBurstTime;
    int iPriority;
};

В основной функции generateProcess () возвращает указатель на процесс. Этот указатель помещается в связанный список, и поэтому я пытаюсь получить доступ кПеременная oTimeCreated, которая является частью той структуры, которая является главой списка.

1 Ответ

0 голосов
/ 18 октября 2019

Ошибка не о Head, а о Head->pData. Обратите особое внимание на сообщение об ошибке. В некоторых компиляторах сообщение об ошибке четко идентифицирует строку, но не точное местоположение в строке;если ошибки вашего компилятора не ясны, вы можете получить более точное местоположение ошибки, если добавите разрывы строк и создадите больше промежуточных переменных.

void *data = Head->pData;
struct timeval time_created = data->oTimeCreated;
int responseTime = getDifferenceInMilliSeconds(time_created, start);

Обратите внимание, что для написания кода таким образом, я должен был датьтипы к промежуточным выражениям Head->pData и data->oTimeCreated. Чтобы выяснить, какие типы дать, я посмотрел определения struct element и struct process.

В частности, тип Head->pData равен void*. Это указатель на неопределенный тип. Вы не можете разыменовать его, и, в частности, data->oTimeCreated приводит к ошибке компиляции, поскольку data не является указателем на структуру или объединение. Неуказанный тип не является структурой или объединением.

C не имеет полиморфизма , запеченного в языке. Он допускает полиморфизм через указатели void, но, как и во многих вещах в C, вам нужно выполнить часть работы самостоятельно. C не отслеживает фактический тип объекта, если у вас есть только пустой указатель на него. Вы должны указать, когда вы хотите разыменовать указатель, и вам нужно сделать его правильно, иначе может произойти все, что угодно .

Если вы уверены, что то, что вы положили в список,указатель на struct process, который все еще действителен, затем преобразуйте или приведите пустой указатель к указателю на struct process. Вот идиоматический способ сделать это:

struct process *head_process = Head->pData;
runPreemptiveJob(head_process, &start, &end);
int responseTime = getDifferenceInMilliSeconds(head_process->oTimeCreated, start);
...