队列中的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?
答案 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 -字面意思是“计算机可能会做任何事情”-而您应该避免这种情况(您可能会认为,可能发生的最糟糕的事情是您获得了垃圾值,但是当优化程序介入时,它们往往会被诸如此类的东西所迷惑)