运行时检测内存删除
代码:
int *ptr = new int[10];
int *q = ptr;
delete q;
工作正常,没有任何问题(没有运行时错误)。
但是,以下代码:
int *ptr = new int[10];
int *q = ptr;
q++;
delete q;
会导致运行时错误。
我使用 Microsoft Visual Studio-8 和 Win-7 作为平台。
我无法弄清楚为什么在第二种情况下会出现运行时错误?
The code:
int *ptr = new int[10];
int *q = ptr;
delete q;
works fine without any issues (no run-time error).
However, the following code:
int *ptr = new int[10];
int *q = ptr;
q++;
delete q;
results in run-time error.
I am using Microsoft Visual Studio-8 and Win-7 as platform.
I am not able to figure out why there is a run-time error in the second case?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您的代码导致未定义的行为。未定义的行为意味着任何事情都可能发生,但行为无法定义。该程序的运行纯粹是靠运气,其行为无法解释。
基本上,
如果您使用
new
分配动态内存,则必须使用delete
来取消分配它。如果您使用
new[]
分配动态内存,则必须使用delete[]
来取消分配它。将
new
未返回的任何地址传递给delete
是未定义的行为。这是标准的引用。
根据C++03 标准§ 3.7.4.2-3:
在 C++ 中,最好使用 RAII(SBRM)智能指针而不是原始指针,它会自动处理内存释放。
Your code is causing an Undefined Behavior. An Undefined Behavior means anything can happen, the behavior cannot be defined. The program works just by pure luck its behavior cannot be explained.
Basically,
If you are allocating dynamic memory with
new
you MUST usedelete
to deallocate it.If you are allocating dynamic memory with
new[]
you MUST usedelete[]
to deallocate it.It is undefined behavior to pass any address to
delete
which was not returned bynew
.Here is the quote from the Standard.
As per C++03 Standard § 3.7.4.2-3:
In C++ it is better to use RAII(SBRM) by using Smart pointers instead of raw pointers, which automatically take care of the memory deallocations.
这里有两个错误:
删除
未由new
返回的指针。删除
由new[]
返回的指针——您需要使用delete[]
。因此,第一个片段的工作只是巧合,并且没有错误只是因为您使用的是原始类型。如果是 UDT,析构函数将不会运行。
此外,您应该使用容器和智能指针,而不是原始的
new
和delete
。There are two errors here:
delete
a pointer that wasn't returned bynew
.delete
a pointer that was returned bynew[]
— you need to usedelete[]
.So, the first snippet works only by coincidence, and there is no error only because you're using a primitive type. If it were UDT, the destructors wouldn't run.
Also, you should be using containers and smart pointers, instead of raw
new
anddelete
.因为您必须传递 new 的未更改结果来删除。这就是事情的工作原理,即 new/delete 的 API 契约。
Because you have to pass the unaltered result of new to delete. That is just how things work, i.e. the API contract of new/delete.
因为您更改了
q
指向的地址,然后尝试删除它。您应该永远尝试
删除
任何new
返回给您的内容。其他任何行为都是未定义的行为。Because you changed what address
q
points at, and then tried to delete it.You should only ever try to
delete
whatevernew
returns to you. Anything else is undefined behavior.