【问题标题】:Question about pointers and objects?关于指针和对象的问题?
【发布时间】:2009-10-16 22:28:15
【问题描述】:

只是想知道,如果我静态地创建了一个将指针作为数据成员的对象,然后该对象超出了范围,那么指针会发生什么? 楚马

【问题讨论】:

  • 在您的情况下,“静态创建”是什么意思?您认为“超出范围”一词的含义是什么?
  • 我编辑了我接受的答案,你可能想再看一遍。

标签: c++ pointers scope


【解决方案1】:

指针根本没有发生任何事情,它只是不复存在。如果它指向需要释放的东西,那么你只是发生了内存泄漏。

要么向析构函数中添加代码以正确清理指针,要么使用自动清理的“智能指针”。

编辑:如果您实际上的意思是创建一个静态对象,通过在函数内使用 static 关键字声明它,那么答案就不同了。静态对象,一旦由声明它的函数的第一次执行构建,将继续存在,直到程序结束。它的数据成员,包括指针,将保持有效。对该函数的后续调用将访问同一对象。如果对象分配了任何内存,它将保持分配状态,除非有什么明确删除它。

【讨论】:

  • (因为它在另一个回复下引发了一些讨论:)这里可能毫无价值,虽然在日常 C++ 术语中,“超出范围”通常 [mis] 用来表示“到死,结束它的生命”,“走出范围”的正式含义与“不复存在”无关。马克显然是从前一种意义上解释了这个术语,而且很可能 OP 也是这样做的。因此,在假设的解释中,马克的回答是“正确的”。不过形式上,在一般情况下,当对象超出范围时,它们不会停止存在,也不会调用它们的析构函数。
  • 当然可以在词法范围之外执行,但不可能(除了线程之外)在动态范围之外执行。对于大多数 C++ 目的,我不确定“超出范围”是否有很好的用途,这并不意味着离开定义变量的块。
  • @David Thornley:再一次,每次离开块时,块内定义的静态变量都会超出范围。这不会使它“不复存在”。此外,“范围”的概念在语言的一些重要特性的定义中被大量使用(如名称查找)。我想说的是,宣传这样一个重要术语的错误定义并不是一件好事。简单来说,在 C++ 中,“超出范围”意味着“对非限定名称查找不可见”。
  • 我假设“静态创建”是用词不当,而他实际上的意思是“本地创建”。现在我再想一想,我意识到他可以在函数中声明一个静态对象——当然会有完全不同的答案。
  • 不,它不是使用静态创建的。我不知道任何其他方式可以说它不是使用 new 关键字创建的。
【解决方案2】:

指针与对象的其余部分一起被销毁。无论它指向什么都不会受到影响(除非对象的析构函数对其进行了处理)。

【讨论】:

    【解决方案3】:

    修改后的答案

    这里有两个相关的变量属性——作用域和生命周期——我认为问题是把两者混为一谈。

    在我能想到的所有上下文中,静态分配的对象的生命周期本质上就是进程的生命周期。有一些关于对象首次初始化(构造)的确切时间的技术细节,但最终结果基本相同 - 在整个过程中存在一个静态分配的对象。

    但是,当控制线程在程序中的函数之间移动时,对象可能会进入范围,也可能会超出范围。对象的范围是按名称可见的地方。如果将指向它的指针(或对它的引用)传递给其他不在范围内的函数,则它可以在其他地方访问。

    由于静态分配的对象具有程序持续时间的生命周期,因此该对象的指针成员不会因为对象超出范围而改变;对象继续存在不变,指针成员继续指向同一个地方。显然,如果静态分配对象中的指针指向具有自动持续时间的变量,并且该指向的变量因为被销毁而不再存在,那么静态分配对象中的指针指向无效位置。

    不过,关键是静态分配的对象没有变化,指针成员也没有变化,只是作用域发生了变化。并且没有因范围变化而导致的泄漏。


    原答案

    在我能想到的所有上下文中,静态分配的对象都不能超出范围,几乎按照定义。我想如果一个共享库被加载然后卸载,那么一个静态分配的对象可能会“超出范围”,否则......

    如果这个前提是正确的,那么问题的后半部分就很简单了。您可以采用两种视图中的任何一种:

    1. 由于静态对象永远不会超出范围,因此静态对象及其指针成员不会发生任何事情,并且当对象返回范围时它将指向同一个位置 - 这里的范围意味着“进入一个函数可以访问静态对象'。
    2. 当控制线程离开可以访问静态对象的作用域时,静态对象及其指针成员不会发生任何事情,并且当对象下一次回到作用域时,它将指向同一个位置。

    这基本上是在说同样的事情,两次。如果我说第三次,它就会自动成为真的,不是吗?因此,静态分配的对象不会超出范围(即使它并不总是可以从当前函数访问),因此指针成员不会发生任何事情。那里……我说的是这样。我想!

    我错过了什么? “静态创建的对象”是否有我没有想到的含义?

    【讨论】:

    • 显然您误解了“范围”的概念。 C++ 中的作用域是声明实体名称可见的区域。在 C++ 中,“超出范围”并不意味着“死亡”。差远了。例如,每次函数返回时,函数中声明的静态对象都会超出范围。然而,它不会死。下次您进入该函数时,您会看到同一个对象还活得好好的。看起来OP也误解了“范围”或“静态”的一些东西。不知道是哪个...
    • @Andrey:我表达得不够好——你说的是我想说的——我曾经(现在仍然)是一个但对回答“指针根本没有发生任何事情,它只是不复存在。如果它指向需要释放的东西,那么你只是发生了内存泄漏。”目前被选为“最佳”。 “停止存在”和“泄漏”部分与我对正在发生的事情的理解相反。
    • 当然同意 AndreyT。另见stackoverflow.com/questions/1388685/…
    猜你喜欢
    • 2011-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-24
    • 2014-05-13
    • 2015-09-27
    相关资源
    最近更新 更多