默认参数中的c ++ new运算符及其副作用

时间:2018-03-17 13:04:45

标签: c++

我对c ++中的默认参数有疑问。如果我有这样的功能:

int foo(int* obj = new Int(4)) {
    /* Stuff with obj. */
}

现在,当然,整数在这里只是用作一个例子,但问题是我是否要像这样为参数提供一个值:

int x = 2;
foo(&x);

表达式obj = new Int(4)是否仍然会被评估,即使我为参数提供了一个值,因此分配了一些内存,然后我就无法读取它了?

2 个答案:

答案 0 :(得分:2)

不,默认参数仅在没有传递参数时使用。 new不会被调用,因此不会有内存分配。另外,正如一些程序员老兄所说,如果你不在功能体内部(或外部)的某个点进行清理,你会发生内存泄漏。

答案 1 :(得分:2)

使用new表达式作为参数的默认值,如

 int foo(int *obj = new int(4));

是一个非常糟糕的主意,因为可能的用例彼此之间的行为不一致,以及一些可能的坏结果。

让我们说,为了讨论,foo()的实现确实

 delete obj;

如果调用者执行

中的任何一个,那也没关系
 foo();             //  default argument is a new expression
 foo(new int(2));

但如果调用者执行一个或多个;

,则会导致未定义的行为
 foo(&some_int);      //  some_int is a variable local to the caller
 foo(new int[2]);     //   dynamically allocates an array

相反,我们假设foo()没有delete obj。在这种情况下,这些陈述中的任何一个

 foo();
 foo(new int(3));
 foo(new int [2]);      // dynamically allocates an array

导致内存泄漏,

  foo(&some_int);

可能会正常工作(假设foo()没有以其他方式调用未定义的行为。)

真正的问题是foo()无法(在标准C ++的范围内)检测上述调用者所做的事情。因此存在未定义行为或内存泄漏的真实风险,除非调用者确实完全正确“(”正确的事情“意味着不会导致内存泄漏或未定义的行为)。并且,由于有更多选项可以做错误的事情,因此调整者不会做正确的事情。请记住,程序员在阅读文档方面非常糟糕,因此依赖文档是一种很难确保调用者(或程序员在调用者中编写代码)能够做到避免上述问题所需的方法。