为什么当我尝试对使用 New 函数启动的对象调用删除函数时出现范围错误?

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 为什么      更新时间:2023-10-16

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

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

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

如果没有指向已分配对象的指针,则无法将其删除。这就是编译器所抱怨的:指针a在 while 循环之外不存在!因此,在它看到delete(a);的这一点上,它丝毫不知道a可能是什么,就它而言,它还没有被定义。

因此,在 while 循环之后,对象本身仍然存在,但指向对象的指针不存在!

错误消息是不言自明的;尽管使用new创建的对象即使在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)放在右大括号之前。

您需要在循环中删除。

即更改线条

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

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

这样a就在范围内

在您的情况下,您是在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

您可以在此处阅读有关示波器的更多信息。 希望这有帮助。