内存泄漏还是不是呢?

3

我有一小段代码,它在一个更大的代码中:

int *p = new int[100];
p += 50;
delete []p;

编译器只会删除第51个内存位置吗?我认为是的。然而,在数组指针的情况下,编译器会多持有一个项,用于告知分配的对象数量。所以,在这种情况下,它是否应该删除超出分配大小的内存?还是它会删除第51-100个元素,并将1-50个元素保留在内存中,这种情况下可能会发生内存泄漏。


2
未定义行为。可能会泄露信息。也可能会崩溃或擦除硬盘数据。 - Grizzly
或者启动一个流氓进程并成为一名考古学家。 - Cubic
3个回答

6

这实际上是未定义的行为。你只能 delete / delete[] 你从 new / new[] 获取的东西。


5

这是未定义的行为。C++标准说:

3.7.4.2 回收函数

3 ... 否则,如果标准库中提供给operator delete(void*)的值不是之前调用operator new(std::size_t)operator new(std::size_t, const std::nothrow_t&)返回的值之一,则其行为未定义;如果标准库中提供给operator delete[](void*)的值不是之前调用operator new[](std::size_t)operator new[](std::size_t, const std::nothrow_t&)返回的值之一,则其行为未定义。

4 ... 使用无效指针值(包括将其传递给回收函数)的效果是未定义的。(在某些实现中,它会导致系统生成的运行时错误。)


我突然想到:实现newdelete能否提供更多保证,或者说即使delete的实现可以从结构体内部恢复指针,标记为“未定义行为”是否意味着编译器也可能搞砸它?在我看来,它确实可能会搞砸(毕竟是未定义的,不是未指定的),我想知道是否有任何编译器具有逻辑,实际上会导致出错; 我知道某些编译器能够省略 malloc/ free 调用对,当缓冲区未使用时,因此它们肯定在这些领域辛苦。 - Matthieu M.
未定义行为意味着标准没有告诉编译器厂商应该发生什么。编译器实际上可能会生成代码来释放第51到100个数组元素。它也可能会崩溃你的程序,或者简单地搞砸某些东西。它也可能会删除你的色情文件夹。毕竟这是未定义的行为 :) 话虽如此,你可能找不到任何一个实现会释放一半的数组。大多数情况下,你要么看到崩溃,要么看到一个静默的错误,可以使任何事情发生。 - s3rius

1
编译器不会分配或删除内存,如果您在指针值上调用free,而该指针值不是从new获取的,则取决于操作系统会发生什么。唯一可以保证的是这是错误的。

是的,但这只是一个注释,不是一个答案。 - user395760
实际上,你错了。这不是操作系统的问题。这是运行时库(通常与编译器捆绑在一起),它提供了一般的内存处理设施(mallocnew)。通过一些魔法,new可以被用户覆盖。 - Matthieu M.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接