Как реализовать функцию enque без использования встроенной функции malloc? - PullRequest
0 голосов
/ 18 апреля 2019

Функция enque в очереди (с использованием связанной структуры данных) обычно используется с функцией malloc (). Однако я пытаюсь реализовать это немного иначе, избегая использования malloc () следующим образом.

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

 void enque(queue* qp, int x) // queue is a struct that holds front and rear node address
{
  queueNode a;  // queueNode is a struct with data and next pointer
  a.data = x;
  a.next = NULL;

  if(isEmpty(qp))
  {
    qp->front = &a;
    qp->rear = &a;
  }
  else
  {
    qp->rear->next = &a;
    qp->rear = qp->rear->next;
  }
}

Основная функция

int main()
{
 queue q;
 int c;
 initialize(&q);

 enque(&q, 11);

 printf("\n %d",(&q)->front->data);
 printf("\n %d",(&q)->front->data);

 return 0;
}

Вывод выглядит следующим образом:

11

некоторое значение мусора

Почему во второй раз печатается значение мусора, а не 11?

Ответы [ 2 ]

0 голосов
/ 18 апреля 2019

a является локальной переменной, поэтому при завершении функции enque переменная a уничтожается.

Теперь в C и C ++ слово "destroy" не обязательно означает, что данные больше не находятся по этому адресу.Это означает, что данные могут больше не находиться по этому адресу, поскольку этот адрес может быть повторно использован для других целей в любое время.Вы не можете ожидать, что это все еще будет там.

На практике , если вы не используете оптимизацию , то, что , скорее всего, произойдет, это то, что пространство, где хранились локальные переменные enque, будетполучить повторно при следующем вызове функции.Между enque возвратом и чтением (&q)->front->data нет вызова функции (printf не вызывается, пока не получен доступ к значению), поэтому значение 11 все еще находится в этом месте.Затем вызвал printf, и printf имеет несколько локальных переменных, которые хранятся в той же ячейке памяти, где были локальные переменные enque.Поэтому во второй раз, когда вы читаете (&q)->front->data, вы читаете одну из локальных переменных из последнего вызова printf вместо одной из локальных переменных из enque.

Примечание: Это ненадежновообще - вы можете получить другие результаты, если будете использовать другой компилятор, другую версию того же компилятора, другую версию вашей операционной системы, другую версию библиотеки, если вы включите оптимизацию или еслипланеты не выровнены правильно.Он мог бы дать вам 11 раз, значения мусора оба раза, сбой или даже более странные вещи (т. Е. Именно поэтому это называется неопределенное поведение - буквально означающее «компьютер может делать все что угодно» - и вам следуетизбегайте этого (вы можете подумать, что худшее, что может случиться, - это получить мусор, но когда оптимизаторы включаются, их, как правило, смущают подобные вещи)

0 голосов
/ 18 апреля 2019

Ваша программа имеет UB. Этот метод не будет работать. Если вы не хотите использовать malloc, вам нужен глобальный пул узлов.

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