运行时检测内存删除

发布于 2024-11-27 02:49:15 字数 314 浏览 2 评论 0原文

代码:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

感情洁癖 2024-12-04 02:49:15

您的代码导致未定义的行为。未定义的行为意味着任何事情都可能发生,但行为无法定义。该程序的运行纯粹是靠运气,其行为无法解释。

基本上,

如果您使用new分配动态内存,则必须使用delete来取消分配它。

如果您使用new[]分配动态内存,则必须使用delete[]来取消分配它。

new 未返回的任何地址传递给 delete 是未定义的行为。
这是标准的引用。

根据C++03 标准§ 3.7.4.2-3:

如果释放函数因抛出异常而终止,则行为未定义。提供给释放函数的第一个参数的值可以是空指针值;如果是这样,并且如果释放函数是标准库中提供的函数,则调用无效。否则,提供的值
标准库中的运算符 delete(void*) 应是先前调用运算符 new(std::size_t)返回的值之一标准库中的operator new(std::size_t, const std::nothrot_-t&),以及提供给标准库中的operatordelete[](void*)的值应是其中之一先前调用 operator new[](std::size_t)
标准库中的operator new[](std::size_t, const std::nothro_t&)

在 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 use delete to deallocate it.

If you are allocating dynamic memory with new[] you MUST use delete[] to deallocate it.

It is undefined behavior to pass any address to delete which was not returned by new.
Here is the quote from the Standard.

As per C++03 Standard § 3.7.4.2-3:

If a deallocation function terminates by throwing an exception, the behavior is undefined. The value of the first argument supplied to a deallocation function may be a null pointer value; if so, and if the deallocation function is one supplied in the standard library, the call has no effect. Otherwise, the value supplied
to operator delete(void*) in the standard library shall be one of the values returned by a previous invocation of either operator new(std::size_t) or operator new(std::size_t, const std::nothrow_-t&) in the standard library, and the value supplied to operator delete[](void*) in the standard library shall be one of the values returned by a previous invocation of either operator new[](std::size_t) or
operator new[](std::size_t, const std::nothrow_t&) in the standard library.

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.

那支青花 2024-12-04 02:49:15

这里有两个错误:

  1. 您无法删除未由new返回的指针。
  2. 您无法删除new[]返回的指针——您需要使用delete[]

因此,第一个片段的工作只是巧合,并且没有错误只是因为您使用的是原始类型。如果是 UDT,析构函数将不会运行。

此外,您应该使用容器和智能指针,而不是原始的 newdelete

There are two errors here:

  1. You can't delete a pointer that wasn't returned by new.
  2. You can't delete a pointer that was returned by new[] — you need to use delete[].

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 and delete.

淡看悲欢离合 2024-12-04 02:49:15

因为您必须传递 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.

请叫√我孤独 2024-12-04 02:49:15

因为您更改了 q 指向的地址,然后尝试删除它。

您应该永远尝试删除任何new返回给您的内容。其他任何行为都是未定义的行为。

Because you changed what address q points at, and then tried to delete it.

You should only ever try to delete whatever new returns to you. Anything else is undefined behavior.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文