Почему `pLQ-> tail` является нулевым указателем? - PullRequest
0 голосов
/ 11 ноября 2018

Я работаю над очередью и продолжаю сталкиваться с проблемами с постановкой в ​​очередь. Вот то, что я считаю соответствующим кодом:

typedef struct Qnode QNODE;
struct Qnode
{
  int length;
  QNODE* next;
  QNODE* prev;
};

typedef struct lqueue lQUEUE;
struct lqueue
{
   QNODE *head;
   QNODE *tail;
};

lQueue lqueue_init_default(void)
{
lQUEUE* pQ = NULL;
pQ = (lQUEUE*)malloc(sizeof(lQUEUE));
if (pQ != NULL)
{
    pQ->head = NULL;
    pQ->tail = NULL;
}
pQ->head = pQ->tail;
return pQ;
}

Status lqueue_henqueue(lQueue* hLQ, int lc)
{
lQUEUE* pLQ = (lQUEUE*)hLQ;
QNODE* new = (QNODE*)malloc(sizeof(QNODE));
if (new == NULL)
{
    printf("Couldn't allocate space.\n");
    return FAILURE;
}
new->length = lc;
new->next = pLQ->tail->next;

pLQ->tail = new;
return SUCCESS;
}

Всякий раз, когда я пытаюсь запустить программу, я получаю эту ошибку во время выполнения:
Исключение: нарушение прав на чтение. pLQ->tail был нулевым.
Почему это нулевой указатель? Связано ли это с функцией инициализации?
Вот как это называется:

int cl = 0;//Individual car length
lQueue hLQ = lqueue_init_default();//Handle to the left queue
printf("Enter the length of the lcar:\n");
            scanf("%d", &cl);
            lqueue_henqueue(hLQ, cl);

1 Ответ

0 голосов
/ 11 ноября 2018

Ваш код очень склонен к неопределенному поведению ... Посмотрите на это if утверждение:

if (pQ != NULL)
{
    pQ->head = NULL; // This pointer is now 'NULL'
    pQ->tail = NULL; // This is also 'NULL'
}

Какой должен быть этим ...

if (pQ != NULL)
{
    pQ->head = (QNODE*)calloc(1, sizeof(lQUEUE)); // This is proper pointer initialization...
    pQ->tail = (QNODE*)calloc(1, sizeof(lQUEUE));
}

А это:

lQueue lqueue_init_default(void)

должно быть так:

lQueue * lqueue_init_default(void) // Since you are returning a pointer...

Вы увидите, что код работает нормально, потому что нет неопределенного поведения ...

Обратите внимание, что вы можете никогда не обращаться к объекту, который присвоен NULL ... ( Только если вы не хотите, чтобы ваша программа работала неопределенно ...) Итак, это:

pQ->tail = NULL;

это небезопасно , по крайней мере ... Структурные указатели, назначаемые на NULL, обычно видны только тогда, когда они уничтожены ... Пример приведен ниже ...


Кроме того, не имеет отношения к , но имеет деструктор для структуры и вызывает ее, когда вам больше не нужна структура, или она утечет память потом ...

void destroy_lqueue(struct lqueue ** queue)
{
    if (queue != NULL)
        queue = NULL;
    free(queue);
}
...