【问题标题】:Why am I getting a scope error when I try to call the delete function on an object I initiated using the New function?当我尝试在使用 New 函数启动的对象上调用 delete 函数时,为什么会出现范围错误?
【发布时间】:2016-12-27 01:08:04
【问题描述】:

我正在练习动态内存分配,所以我在这里创建了一个对象,一个名为 vector3d 的自定义数据类型,一个我在不同文件中定义的数学向量。但是,当我尝试使用 delete 删除对象时,我收到一个编译器错误,指出测试向量未在该范围内定义。但是,我在对象析构函数中有一个调试 cout 打印函数,以确保它被调用并且没有被调用。

int main()
{
    while(continueProgram == true)
    {
        vector3d *a;
        a = new vector3d("Test vector");
        std::cout << a->getName() << std::endl;

        vector3d b("Test vector 2");
        std::cout << b.getName() << std::endl;


        continueProgram = prompt(); // Boolean
    }
    delete(a); // <-- "Error: 'a' was not declared in this scope"

return 0;
}

这里是构造函数和析构函数,还有vector3d打印函数。

vector3d::vector3d(std::string s)
:name(s)
{
    std::cout << "Vector constructor initialized" << std::endl;
}

vector3d::~vector3d()
{
    std::cout << "Vector destructor initialized" << std::endl;
}

void vector3d::printVector()
{
    std::cout << "Name: " << this->name << std::endl;
}

我不明白为什么我不能在这里调用 delete 函数,因为我认为使用 New 关键字的全部意义在于将对象保留在其范围之外。否则我只会初始化为

vector3d a("Test vector");

就像我对 vector3d b 所做的那样,对吧?我不明白为什么我会在这里遇到范围错误

这是程序在运行时的控制台输出,当我注释掉删除行并键入“n”结束程序时:

Vector constructor initialized
Test vector
Vector constructor initialized
Test vector 2
Continue program? y/n
n
Vector destructor initalized

所以只有vector3d b出现的析构函数,而不是vector3d a

【问题讨论】:

  • // 编译器是正确的。 a 在 while 循环中声明。
  • 我将如何删除该对象?有没有办法指定我指的是哪个对象?

标签: c++ memory-leaks


【解决方案1】:

确实,分配有new 的对象存在,只要它们不是程序(或一段时间后的操作系统)的deleted。但是你仍然需要内存地址来删除对象。

如果没有指向分配对象的指针,就不能删除它。这就是您的编译器所抱怨的:指针a 在while 循环之外不存在!因此,在它看到delete(a); 时,它根本不知道a 可能是什么,就它而言,它还没有被定义。

所以,在while循环之后,对象本身还是存在的,但不是指向对象的指针!

【讨论】:

  • 谢谢你的解释,这正是我需要的
【解决方案2】:

错误信息是不言自明的;尽管使用 new 创建的对象 continue 即使在 while 循环之后仍然存在,但指向它的局部变量 a 停止 存在越过最里面的右大括号时的范围}:

while(continueProgram == true)
{
    vector3d *a;
    a = new vector3d("Test vector");
    //....
} // `a` goes out of scope
delete(a); // <-- "Error: 'a' was not declared in this scope"

delete(a) 放在右大括号之前。

【讨论】:

    【解决方案3】:

    你需要在循环中删除。

    即换行

    }
    delete(a); // <-- "Error: 'a' was not declared in this scope"
    

    delete(a); // <-- "Error: 'a' was not declared in this scope"
    }
    

    所以a 在范围内

    【讨论】:

      【解决方案4】:

      在您的情况下,您在 while 内声明 vector3d *a。这意味着您不能在while 范围之外使用a

      while(true) {//start of the while scope int a = 0; }//end of the while scope

      在您的代码中,您不会在每次使用new 时删除您在内存中分配的vector3d。 要删除a,请将delete(a) 移动到定义a 的范围内。

      注意:例如,范围可以在任何地方创建

      int main()
      {//start of the main scope
        int a = 0;
        {//start of a new scope
          int b = a; //a can be used here because this scope inside the main scope
        }//end of scope
      
        b = 2; //error b is out of scope
      
      }//end of main scope
      

      您可以阅读更多关于范围here 的信息。 希望这可以帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-05
        • 1970-01-01
        • 2021-09-10
        • 2021-12-21
        • 2022-01-26
        相关资源
        最近更新 更多