Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.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++; 我正在学习C++的教程。在关于使用new和delete()动态内存分配的课程中,它指出:_C++_Dynamic Memory Allocation - Fatal编程技术网

在C++; 我正在学习C++的教程。在关于使用new和delete()动态内存分配的课程中,它指出:

在C++; 我正在学习C++的教程。在关于使用new和delete()动态内存分配的课程中,它指出:,c++,dynamic-memory-allocation,C++,Dynamic Memory Allocation,类似地,删除动态分配的变量时,指向该变量的指针不是零。考虑下面的片段: 然而,当我尝试它(编译器:GNU GCC编译器,ubuntu)时,我的程序并没有崩溃 int *pnValue = new int; delete pnValue; // pnValue not set to 0 if (pnValue) *pnValue = 5; // will cause a crash -> doesn't std::cout << "Did not crash" <&

类似地,删除动态分配的变量时,指向该变量的指针不是零。考虑下面的片段:

然而,当我尝试它(编译器:GNU GCC编译器,ubuntu)时,我的程序并没有崩溃

int *pnValue = new int;
delete pnValue; // pnValue not set to 0
if (pnValue)
    *pnValue = 5; // will cause a crash -> doesn't
std::cout << "Did not crash" << std::endl;
int*pnValue=newint;
删除pnValue;//pnValue未设置为0
如果(pnValue)
*pnValue=5;//将导致崩溃->不会

std::cout你的程序不会因为你运气好而崩溃(或者运气不好,谢谢@user1320881,因为你可能无法在更复杂的代码中检测到这样的事情,并且以后可能会发生一些崩溃或严重的副作用)。事实上,这里有未定义的行为,任何事情都可能发生(不一定是崩溃)。从技术上讲,您的程序不会崩溃,可能是因为操作系统尚未回收该部分内存,并且您没有覆盖属于其他进程的内存,但是你永远不应该写这样的代码。

编辑:在几句评论之后,简短的回答——也许是最好的答案——是行为没有定义

C++在删除后不强制将指针指向NULL,因此指针可能仍然具有并且很可能具有对解除分配的内存的内存引用

如果内存引用确实存在,则不存在空指针异常。它可能不会崩溃,因为您对引用的内存所做的操作不会被注意到

只要您只是在堆中使用为进程分配的内存,操作系统就不会注意到无效引用。若删除操作将释放为堆保留的一些操作系统内存,那个么它将崩溃,但这不太可能发生

< > >强> C++库的堆管理器可能不会注意到/强>对已释放内存的访问——这是依赖于实现的。 您自己的程序可能也不会受到影响,因为您尚未完成可能会重用刚刚释放的内存的分配

<> >强> C++编译器没有注意到这个< /强> -它也不强制执行内存分配对象的运行时引用计数,也不执行任何引用的有效性的运行时检查。编译器很高兴您为指针引用的内存分配了正确类型的变量


在C++中,内存分配不仅难以管理,而且会造成严重的问题。这就是为什么它是一个好的实践,它也可以与C++一起使用,并有专用于C++的库。

欢迎使用C++中的<强>未定义行为< /强>。虽然你的问题已经得到了直接的回答,但由于你对这门语言还不熟悉,我建议你谈谈这个话题。我相信他们会澄清你以后可能遇到的许多问题。

我会认为它是“不吉利的”:)——如果它崩溃了会更好,这样你就可以捕捉到错误。一个程序在这个操作之后崩溃的更可能的原因是损坏的堆元数据。许多Allcator将在释放的块中存储诸如链表指针之类的控制结构。该教程中的关键短语是:…这几乎不可避免地会导致程序崩溃*-强调我的。也许它最终应该添加到这句话中。
是否有任何形式的运行时检查在C++
中不是为了这个,而是为了大多数其他事情(例如越界数组访问和类似错误)。你必须仔细编写代码,以免犯错误。二十世纪,该网站在C++教学方面做得很好。RE将导致崩溃——这是无法保证的。无法预测当您分配到该内存位置时会发生什么。行为未定义。此代码几乎肯定不会崩溃。但如果它真的这样做了,它几乎不可避免地会以一种非常令人惊讶的方式出现在程序中一个不相关的部分,并且很难调试。顺便说一句,有像
valgrind
这样的工具可以帮助你找到这些bug。我不明白你所说的“小心”是什么意思。答案很简单,它是未定义的行为。@tenfour好吧,我想这是一种说法:)但仅仅说它的行为是“未定义”并不能帮助理解为什么它不会崩溃堆分配器可能关心未来的分配,尽管根据您的评论编辑了答案。
int *pnValue = new int;
delete pnValue; // pnValue not set to 0
if (pnValue)
    *pnValue = 5; // will cause a crash -> doesn't
std::cout << "Did not crash" << std::endl;