2013-05-03 55 views
2

我只是不小心写下面的代码。 它在linux环境下使用gcc 4.4.7进行编译。C++新的运营商使用问题

int main() 
{ 
     new int; 
     return 0; 
} 

我很惊讶编译器没有指出任何错误或警告。 C++标准提到了这个吗?在这种情况下是否仍有可能防止内存泄漏?任何建议是受欢迎的。

+4

没有错误或警告信号,因为这是完全有效的C++。不,你不能做任何有关泄漏的事情。 – Mat 2013-05-03 10:21:49

+0

@Mat:你应该做出答案而不是评论 – Skizz 2013-05-03 10:22:41

+0

问题是存在合法的内存泄漏。许多大型程序(例如GCC)在初始化时分配一些堆数据,并且不要打扰它。 – 2013-05-03 10:23:05

回答

1

这就是为什么您应该尽量避免在新代码中尽可能使用原始“新”的原因之一。 std :: make_shared和C++ 14 std :: make_unique更安全,因为它们将通过返回知道何时以及如何删除对象的shared_ptr和unique_ptr对象来确保正确删除内存。原意是,原始的新版本大多只会在实现数据结构的低级代码中需要。

1

这是没有问题的。这在C++中是有效的。

+2

除了内存泄漏。 – john 2013-05-03 10:23:04

+2

不是所有的“泄漏”都是问题,@john。 – Mat 2013-05-03 10:24:24

+0

不,但是OP专门询问了有关内存泄漏的问题,所以要简单地说这没有问题,而忽略了他的问题。 – john 2013-05-03 10:26:58

1

这是完全有效的C++。你为什么惊讶它编译?

1

为了防止内存泄漏,你应该使用,而不是原始指针的shared_ptr:

#include <memory> 
int main() 
{ 
     std::shared_ptr<int> i(new int); 
     return 0; 
} 

现在新分配的对象在范围结束时删除。你在代码中没有内存泄漏。有关更多详细信息,请参阅C++的动态内存管理11 Dynamic Memory management

+2

除非您需要共享所有权或异常删除,否则您应该使用更简单的'unique_ptr',它的开销不会超过普通指针。当然,如果对象的范围是这样的,那么在没有充分理由的情况下就不应该使用'new'。 – 2013-05-03 10:47:33

0

正如我所评论的,程序可以“合法”泄漏内存。

在大多数操作系统(特别是Posix或Linux)上,内核将在进程exits之后释放进程使用的所有内存。因此,如果程序在其初始化期间分配一些(堆)数据(数量有限),并且根本不打算释放它,则它是“合法的”内存泄漏(并且可能真正的程序表现出这种行为:例如GCC编译器或Firefox浏览器,或大多数X11客户端库等)。

但是,在程序的正常运行期间持续发生并且增加内存消耗的泄漏是不被接受的。

另外,我相信可以证明内存泄漏的静态分析相当于halting problem,因此无法在编译时始终检测它:要么你会得到一些false alarms,要么会有一些泄漏留下来未被发现。

在运行时,您可以使用valgrind来追查内存泄漏。

此外,某些内存区域的活跃程度是该程序的全局属性。阅读更多关于garbage collection,或许可以考虑使用Boehm's conservative GC