指向函数局部结构的指针的范围和生命周期 [英] scope and lifetime of a pointer to struct which is local to a function

查看:50
本文介绍了指向函数局部结构的指针的范围和生命周期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的代码中,我在最后一个节点插入.它工作正常.但我怀疑是因为我最后声明了 Node *;本地,因此每当进行新调用时,都会创建一个新的指针变量,并且在函数终止后将从内存中删除前一个变量.那么 Node * last 是怎么来的呢?是否持有上次调用的地址,因为每次都会重新创建?

In the following code I am inserting at last node. It is working fine. But my doubt is since I have declared Node * last; locally, so whenever a new call is made a new pointer variable will be created and previous one will be removed from the memory after function gets terminated. So how come Node * last; is holding addresses from previous call,since every time it will be freshly created?

第一;是指向链表第一个节点的指针,它是全局声明的.

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

推荐答案

更简单的例子,同样的效果:

Simpler example, same effect:

#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);
}

在你进一步阅读之前,试着找出这段代码的输出是什么.

Before you read further, try to find out what is the output of this code.

你下定决心了吗?

你知道输出是什么吗?

无论您希望此代码打印什么,都是错误的.代码具有未定义的行为,可以产生任何输出.使用 gcc 11.1,这是我得到的输出:

Whatever you expect this code to print, it is wrong. The code has undefined behavior and could produce any output. With gcc 11.1 this is the output I get:

42
42
0

在未初始化时读取局部变量 x 是未定义的行为.你不能那样做!无论如何,一种可能性是下次调用该函数时 42 仍存储在寄存器中,而 x 恰好具有该值.实际上 x 在这种情况下没有任何价值.据说它具有无法读取的不确定价值.

Reading from the local variable x when it is not initialized is undefined behavior. You must not do that! If you do anyhow, one possibility is that next time you call the function the 42 is still stored in a register and x happens to appear to have that value. In fact x has no value in that case. It is said to have an indetermiante value that you cannot read.

当打开优化 (-O3) 时,这是输出:

When turning on optimizations (-O3) this is the output:

0
0
0

很可能编译器意识到代码有 UB 并优化掉了所有无意义的代码.

Most likely the compiler realized that the code has UB and optimized away all non-sense code.

无论您得到什么输出,任何输出都将符合 C++ 标准,因为该标准并没有规定编译具有未定义行为的代码的结果应该是什么.

No matter what output you get, any output would be in accordance with the C++ standard, because the standard does not mandate what should be the result of compiling code with undefined behavior.

TL;DR:始终初始化变量.永远不要从未初始化的变量中读取.具有未定义行为的代码看起来可以工作,但它必须被修复.

TL;DR: Always initialize variables. Never read from an uninitialized variable. Code with undefined behavior can appear to work, but nevertheless it must be fixed.

这篇关于指向函数局部结构的指针的范围和生命周期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆