Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 当我在同一内存中有两个指针时,为什么要调用“delete”两次?_C++_Memory_Memory Management - Fatal编程技术网

C++ 当我在同一内存中有两个指针时,为什么要调用“delete”两次?

C++ 当我在同一内存中有两个指针时,为什么要调用“delete”两次?,c++,memory,memory-management,C++,Memory,Memory Management,我使用new将堆内存分配给指针变量“k”,并将其复制到另一个指针变量“d”中 在这种情况下,我认为这两个变量指向相同的内存,所以删除该内存只需要一个变量;不管是“k”还是“d”。然而,当我删除k时,“k”和“d”仍然指向内存 所以我删除了d,出现了中止陷阱6错误 这是我的测试代码 int* k; k = new int(5); int* d = k; cout<<"d's : "<<d<<endl; cout<<"k's : "<<

我使用new将堆内存分配给指针变量“k”,并将其复制到另一个指针变量“d”中

在这种情况下,我认为这两个变量指向相同的内存,所以删除该内存只需要一个变量;不管是“k”还是“d”。然而,当我删除k时,“k”和“d”仍然指向内存

所以我删除了d,出现了中止陷阱6错误

这是我的测试代码

int* k;
k = new int(5);

int* d = k;

cout<<"d's : "<<d<<endl;
cout<<"k's : "<<k<<endl;

delete d;

cout<<"d's : "<<d<<endl;
cout<<"k's : "<<k<<endl;

delete k;

cout<<"d's : "<<d<<endl;
cout<<"k's : "<<k<<endl;
结果是

d's:0x7fbb56c02ae0 k's:0x7fbb56c02ae0 d's:0x7fbb56c02ae0 k's:0x7fbb56c02ae0

中止陷阱:6

当我删除了d之后,我以为访问“k”和“d”会导致段错误,因为我删除了内存

我错过了什么,有人能帮我吗

然而,当我删除k时,k和d仍然指向内存

对某个指针调用运算符delete将要求操作系统释放与该指针关联的内存,但不会更改指针本身的值。k和d只是继续指向内存中的同一位置,同时释放该位置

这就是为什么有时人们在删除或删除空ptr后会将指针设置为空ptr的原因。在您的情况下,这将使您免于未定义的行为:

delete d;

d = nullptr;
k = nullptr; // Both must be re-assigned

delete k; // Ok, delete on a nullptr is a no-op
然而,当我删除k时,k和d仍然指向内存

对某个指针调用运算符delete将要求操作系统释放与该指针关联的内存,但不会更改指针本身的值。k和d只是继续指向内存中的同一位置,同时释放该位置

这就是为什么有时人们在删除或删除空ptr后会将指针设置为空ptr的原因。在您的情况下,这将使您免于未定义的行为:

delete d;

d = nullptr;
k = nullptr; // Both must be re-assigned

delete k; // Ok, delete on a nullptr is a no-op
当你删除一些东西时,你并不是在破坏内存,你只是把它标记为未使用。您也可以运行析构函数中包含的清理代码,但这是另一回事。内存本身,即物理位和字节,与以前一样保持原位

因此,当删除指针时,指针在删除后仍指向物理内存中的相同字节,但不允许再使用它们。如果你这样做,任何事情都会发生。这甚至适用于指针本身:任何指向已删除内存的指针都不能再被触摸,它立即无效

如果在删除指针后确实使用了它,它可能会正常工作。否则你可能会崩溃。或者,您可以访问使用相同物理内存字节创建的其他内存对象。你根本不知道会发生什么

因此,您最初的想法是正确的:只有两个指针中的一个需要删除,另一个指针在删除后不能再被触碰:

int* k;
k = new int(5);

int* d = k;

cout<<"d's : "<<d<<endl;
cout<<"k's : "<<k<<endl;

delete d;

// cout<<"d's : "<<d<<endl;    //Undefined behavior, the pointer is invalid now
// cout<<"k's : "<<k<<endl;    //Undefined behavior, k is invalid as well

// delete k;    //Undefined behavior, k is invalid
当你删除一些东西时,你并不是在破坏内存,你只是把它标记为未使用。您也可以运行析构函数中包含的清理代码,但这是另一回事。内存本身,即物理位和字节,与以前一样保持原位

因此,当删除指针时,指针在删除后仍指向物理内存中的相同字节,但不允许再使用它们。如果你这样做,任何事情都会发生。这甚至适用于指针本身:任何指向已删除内存的指针都不能再被触摸,它立即无效

如果在删除指针后确实使用了它,它可能会正常工作。否则你可能会崩溃。或者,您可以访问使用相同物理内存字节创建的其他内存对象。你根本不知道会发生什么

因此,您最初的想法是正确的:只有两个指针中的一个需要删除,另一个指针在删除后不能再被触碰:

int* k;
k = new int(5);

int* d = k;

cout<<"d's : "<<d<<endl;
cout<<"k's : "<<k<<endl;

delete d;

// cout<<"d's : "<<d<<endl;    //Undefined behavior, the pointer is invalid now
// cout<<"k's : "<<k<<endl;    //Undefined behavior, k is invalid as well

// delete k;    //Undefined behavior, k is invalid

调用delete两次是未定义的行为。我不清楚你在问什么?取消引用已删除的指针也是未定义的行为。不能期望出现类似段错误的情况。删除指针不会使其无效。这是浪费资源。请参见:学习C++时要记住的关键是,因为代码错误,这并不意味着程序会以你所期望的方式失败。未定义的行为是令人讨厌的,因为它可能看起来好像一切正常。你不必打两次电话,你不能!调用delete两次是未定义的行为。我不清楚你在问什么?取消引用已删除的指针也是未定义的行为。不能期望出现类似段错误的情况。删除指针不会使其无效。这是浪费资源。请参见:学习C++时要记住的关键是,因为代码错误,这并不意味着程序会以你所期望的方式失败。未定义的行为是令人讨厌的,因为它可能看起来很糟糕
一切正常。你不必打两次电话,绝对不能!尽管内存已释放,指针变量的值不会更改。尽管内存已释放,指针变量的值不会更改。我不理解为什么在删除后打印指针k和d的值是UB。“你不能以任何方式取消对这些指针的引用。@DanielLangr有很长一段时间,我也不知道,他成长于一个架构中,指针保存在普通的通用寄存器中。但是,有些体系结构使用包含段部分的专用指针寄存器,将无效值加载到该段指针部分会引发硬件异常。这些体系结构就是为什么在C/C++中传递无效指针是非法的。在现代建筑中,这不是一个问题,但语言规则仍然存在。C++标准如何?它是否指定读取无效指针的值是无效的?只是好奇。我想我找到了:。该行为似乎是从C++14开始定义的,在C++11中未定义。感谢您指出这一点,今天学到了一些新的东西:。@DanielLangr总是很乐意提供帮助:-这就是我感谢讨论的原因:我从他们身上学到了很多:-不明白为什么删除后打印指针k和d的值是UB。“你不能以任何方式取消对这些指针的引用。@DanielLangr有很长一段时间,我也不知道,他成长于一个架构中,指针保存在普通的通用寄存器中。但是,有些体系结构使用包含段部分的专用指针寄存器,将无效值加载到该段指针部分会引发硬件异常。这些体系结构就是为什么在C/C++中传递无效指针是非法的。在现代建筑中,这不是一个问题,但语言规则仍然存在。C++标准如何?它是否指定读取无效指针的值是无效的?只是好奇。我想我找到了:。该行为似乎是从C++14开始定义的,在C++11中未定义。谢谢你指出这一点,今天学到了一些新的东西:@DanielLangr总是很乐意帮助:-这就是我感谢如此多的讨论:我从他们身上学到了很多:-