c++ - 指向函数本地结构的指针的范围和生存期
问题描述
在下面的代码中,我在最后一个节点处插入。它工作正常。但我的疑问是因为我最后声明了 Node *;本地,因此每当进行新调用时,都会创建一个新的指针变量,并在函数终止后从内存中删除前一个变量。那么 Node * 是怎么来的?是否持有上一次通话的地址,因为每次都会重新创建?
第一的; 是指向链表第一个节点的指针,它是全局声明的。
void insertLast(int x)
{
Node *last;
Node *q=new Node;
q->data=x;
q->next=NULL;
if(first==NULL)
first=last=q;
else
{
last->next=q;
last=q;
}
}
insertLast(2);
insertLast(5);
insertLast(7);
display(first);
output:
2 5 7
解决方案
更简单的例子,同样的效果:
#include <iostream>
void DONT_DO_THIS(bool init){
int x;
if (init) x = 42;
else std::cout << x << "\n";
}
void foo() {
int y = 0;
}
int main() {
DONT_DO_THIS(true);
DONT_DO_THIS(false);
DONT_DO_THIS(false);
foo();
DONT_DO_THIS(false);
}
在进一步阅读之前,请尝试找出此代码的输出。
你下定决心了吗?
你知道输出是什么吗?
无论您希望此代码打印什么,它都是错误的。该代码具有未定义的行为并且可以产生任何输出。使用 gcc 11.1,这是我得到的输出:
42
42
0
x
在未初始化时从局部变量中读取是未定义的行为。你不能那样做!如果您无论如何都这样做,一种可能性是下次您调用该函数时,该函数42
仍存储在寄存器中,并且x
恰好看起来具有该值。实际上x
在这种情况下没有任何价值。据说它具有您无法读取的不确定值。
打开优化 ( -O3
) 时,输出如下:
0
0
0
很可能编译器意识到该代码具有 UB 并优化掉所有无意义的代码。
无论您得到什么输出,任何输出都将符合 C++ 标准,因为该标准没有规定编译具有未定义行为的代码的结果应该是什么。
TL;DR:始终初始化变量。永远不要从未初始化的变量中读取。具有未定义行为的代码似乎可以工作,但必须对其进行修复。
推荐阅读
- javascript - 构建项目后“onClick”不起作用
- jquery - 将jquery datepicker的位置更改为顶部
- python - 两个百分比的概率或机会
- javascript - 在音频文件语音到文本 microsoft sdk 中的一段不说话后保持单词偏移
- python - 如果路径有空格,Python检查2个字符串是否代表相同的路径
- c - C 严格别名是否使无类型静态内存池成为不可能?
- javascript - 为什么关键字“this”会在一个函数中被识别,而在同一个 Backbone 视图中却不能识别?
- python - 使用 gmail 时出错,帐户超出带宽
- c# - wsdl 服务中的可选属性
- three.js - Animated text ribbons in Three.js