如何在不使用内置malloc函数的情况下实现enque函数?

时间:2019-04-17 21:15:08

标签: c queue

队列中的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 :(得分:0)

您的程序具有UB。此方法无效。如果您不想使用malloc,则需要有一个全局节点池。

答案 1 :(得分:0)

a是局部变量,因此在函数a完成时,变量enque被破坏。

现在,在C和C ++中,“销毁”并不一定 意味着数据不再位于该地址。这确实意味着数据可能不再位于该地址,因为该地址可以随时用于其他目的。您不能指望它仍然存在。

在实践中,如果您不使用优化,则最有可能发生的是enque局部变量的存储空间将在下一个函数调用中重用。在enque返回和读取(&q)->front->data之间没有函数调用(printf直到访问该值后才被调用),因此11的值仍在该位置。然后printf被调用,并且printf有一些局部变量被存储在与enque的局部变量相同的存储位置中。因此,第二次阅读(&q)->front->data时,您将读取上一个printf调用中的一个局部变量,而不是enque中的一个局部变量。

注意:这根本不可靠-如果您使用其他编译器,同一编译器的不同版本,操作系统的不同版本,其他版本,则可能会得到不同的结果库,如果您启用优化功能,或者行星未正确对齐。可以想象,它两次都会给您11次,两次都给您带来垃圾值,导致崩溃甚至是更奇怪的事情(即,这就是为什么它被称为 undefined behaviour -字面意思是“计算机可能会做任何事情”-而您应该避免这种情况(您可能会认为,可能发生的最糟糕的事情是您获得了垃圾值,但是当优化程序介入时,它们往往会被诸如此类的东西所迷惑)