在控制结构块中定义变量

问题描述 投票:0回答:4

如果我在控制结构的块内定义变量,它是否仅存在于该控制结构块的执行中,而不存在于封闭函数的整个执行中?

另外,我如何监控程序的确切内存使用情况及其变化(即:通过创建和销毁变量来更改内存使用情况)?

后来补充: 在下面的代码中,我知道 v 范围是 if 块,但我想知道 v 是否在 if 块的开始/结束处或函数 func 的开始/结束处在内存中创建/销毁?

void func ()
{
    if (true)
    {
        int v;//automatic storage class
        v = 1;
    }
}
c++
4个回答
2
投票

如果我在控制结构的块内定义变量,它是否仅存在于该控制结构块的执行中,而不存在于封闭函数的整个执行中?

这取决于您在哪里声明变量而不是定义它。

该变量只能在您声明它的范围内访问。如果您显式传递它,它可以超出范围进行访问,但它是否仍然有效将取决于变量的存储类型
例如:

static
变量在整个程序生命周期中保持活动状态,而,
从函数返回自动变量的地址将导致未定义行为,因为该变量在函数返回后不再有效。

好读: 定义和声明有什么区别?

如何监控程序的确切内存使用情况及其变化(即:通过创建和销毁变量来更改内存使用情况)?

我相信您会想要获取有关动态分配对象的信息,因为自动对象仅在其范围内存活足够长的时间,它们会自动销毁,因此通常不会引起任何问题。

对于动态对象,您可以使用内存分析工具,例如 valgrind 和 Massif,或者您可以替换您的类的

new
delete
运算符
并收集诊断信息。


编辑:解决更新后的问题。

在下面的代码中,我知道

v
范围是
if
块,但我想知道
v
是否在if块的开始/结束或函数的开始/结束时在内存中创建/销毁
func

v
在声明它的作用域开始并且声明它的语句被执行时创建。一旦范围结束,即达到
v
}
就会被销毁。
此概念用于形成 C++ 中最广泛使用的概念之一的基础,称为 资源分配即初始化 (RAII)。每个 C++ 程序员绝对必须了解它。

通过这个经过修改的小代码示例可以简单地演示和验证对象的创建和销毁:

#include<iostream>
class Myclass
{
    public:
        Myclass(){std::cout<<"\nIn Myclass Constructor ";}
        ~Myclass(){std::cout<<"\nIn Myclass Destructor";}
};

void func()
{
    std::cout<<"\nBefore Scope Begins";
    if (true)
    {
        Myclass obj;//automatic storage class
    }
    std::cout<<"\nAfter Scope Ends";
}

int main()
{
    std::cout<<"\nBefore Calling func()";
    func();
    std::cout<<"\nAfter Calling func()";
    return 0;
}

输出为:

调用 func() 之前
在范围开始之前
在 Myclass 构造函数中
在 Myclass 析构函数中
范围结束后
调用 func() 后


0
投票

局部变量的作用域仅限于其下面的所有代码 声明直到封闭块的末尾。变量也是 对于包含在原始块中的任何其他块都可见。

更多信息


0
投票

如果局部变量一个对象,那么该对象的生命周期在声明该变量的块的末尾结束。示例:

Foo x;            //  lifetime of "x" begins

{
    some_stuff();

    Foo y;        //  lifetime of "y" begins

    Foo & a = x;  //  local variable "a", no new object

    more_stuff();

}                 //  lifetime of "y" ends; "y" and "a" go out of scope

                  //  (lifetime of "x" ends with its surrounding scope,
                  //   or end of program if it was global)

0
投票

在您的代码示例中,变量

v
if
块的开头和结尾处创建和销毁。这是因为
v
是在
if
语句中本地创建的,因此只能在
if
块的上下文中被识别。当
if
条件变为 false 或块的作用域终止后,变量
v
变得无效并且内存不足。这是因为它是一个自动存储持续时间,这意味着它在进入块时创建并在退出块时销毁。

© www.soinside.com 2019 - 2024. All rights reserved.