C ++ - 动态分配变量的范围

时间:2016-10-28 08:13:40

标签: c++ memory-leaks scope initialization

根据我的学习,需要使用delete运算符删除动态分配的变量,并且不会在范围的末尾自动删除,就像静态变量一样。

因此,在以下示例中,当循环运行第2次和第3次时,不应该“int * p = new int;”由于动态分配的内存“p”尚未被删除,因此被认为是多次初始化?

#include<iostream>
using namespace std;

void main()
{
  int i = 2;

  while (i > -1)
  {
    int *p=new int;

    *p = 5;

    cout << *p;

    --i;
  }
}

使用Visual Studio 2015,上述程序不会出错。根据我的理解,这没有意义。

我认为我对动态分配变量的理解有问题。有人可以澄清一下吗?

3 个答案:

答案 0 :(得分:1)

您的代码显示了所谓的&#34;内存泄漏&#34;。当p超出范围而没有首先delete内存时,为每个循环迭代分配的内存将丢失。这(通常)不会导致编译器警告或运行时错误,因为编译器找到这种错误可能会非常复杂。一些静态代码分析器可能能够检测到这一点。

在内存泄漏的情况下,您可能会注意到,程序运行的时间越长,内存越来越多,这意味着内存泄漏在RAM较低的系统和长时间运行的程序中尤其成问题。系统服务应该运行几天。

有一些特殊的工具可以找到内存泄漏,例如:适用于Linux的valgrind或Visual Studio的调试运行时中的内置工具。

答案 1 :(得分:0)

您不能动态分配变量,只能分配对象。

p不是动态分配的对象,但*p - 由new创建的对象 - 是。
delete p不会删除p,而是删除它指向的对象。

Scope是一个适用于名称的语法编译时属性。

具有名称的变量p具有范围 它指向的对象是未命名的,因此范围的概念甚至不适用于它。

在运行时,p和它指向的对象都有生命周期。

p的生命周期与其范围一致,因为它是一个自动变量。循环的每次迭代都有自己的变量,所有变量都具有相同的名称 - 没有多次初始化,因为变量是不同的。

p指向的对象的生命周期,直到其地址传递给delete为止。
由于您从未这样做,因此使用new“创建的每个对象都会泄漏”。

答案 2 :(得分:0)

p 只是一个包含动态数据地址的静态变量,指针本身在作用域结束时丢失,而动态数据在没有指针访问的情况下持续存在(内存泄漏)。

p 指向的数据是动态内存(在堆中),每次迭代后都不会被释放,但是,变量 p 本身的内容(这是动态数据的地址,如果你去 p在内存中,您会发现它是堆栈中的一个简单数字,它只是堆中动态数据的地址,而不是数据本身)只是堆栈中的一个静态地址,它在作用域结束时丢失(迭代)。