微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么这段代码的输出如下?

如何解决为什么这段代码的输出如下?

#include <iostream>
#include<list>
using namespace std;

int main()
{
   list<int *>l;
   
   for(int i=0;i<3;i++)
   {
       int a = i;
       
       l.push_back(&a);
   }
   cout<<endl;
    for(auto i=l.begin();i!=l.end();i++)
    {
        cout<<**i<<" ";
        
    }
   return 0;
}

我得到的输出2 2 2。是不是因为编译器每次都在同一个地址创建新变量??

Edit1:代码没有做任何事情。我只是写了这段代码作为实验。另外如果代码是这样写的:

#include <iostream>
#include<list>
using namespace std;

int main()
{
   list<int *>l;
   
   for(int i=0;i<3;i++)
   {
       int *a = new int;
       *a = i;
       l.push_back(a);
   }
   cout<<endl;
    for(auto i=l.begin();i!=l.end();i++)
    {
        cout<<**i<<" ";
        
    }
   return 0;
}

现在我得到输出 0 1 2。两者有什么区别?循环运行一次后指针不是也销毁了吗??

解决方法

afor 循环范围内的局部变量,迭代结束时会被销毁。这意味着 push_back 进入 l 的指针是悬空的。对他们的尊重就像 **i 后来导致 UB,一切皆有可能。

编辑

两者有什么区别?循环运行一次后指针不是也销毁了吗??

指针 a 本身被销毁,就像第一个代码片段中类型为 aint 一样;但是 int 指向的 a 没有被销毁。这使得稍后像 **i 格式良好的取消引用,它会打印出 intnew ed 的值。请注意,此代码存在内存泄漏,因为 intnewed 永远不会deleteed。

,

您的代码具有未定义的行为。 l.push_back(&a); 存储循环局部变量的地址。该变量在循环体结束时被销毁。从这一点开始,访问存储指针后面的内存是未定义的行为。对于第二个循环中的 **i 尤其如此。

对于未定义的行为,任何事情都可能发生。请比较Undefined,unspecified and implementation-defined behavior

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。