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



我有一个关于 c++ 中默认参数的问题。如果我有这样的函数:

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

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

int x = 2;
foo(&x);

即使我为参数提供了一个值,因此分配了我无法再读取的内存,表达式是否仍obj = new Int(4)计算?

使用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++的范围内)检测调用者执行上述操作。 因此,存在未定义行为或内存泄漏的真正风险,除非调用者完全执行"正确的操作"(其中"正确的操作"意味着不会导致内存泄漏或未定义的行为)。 而且,由于有更多的选择可以做错误的事情,所以调用者可能不会做完全正确的事情。 请记住,程序员在阅读文档方面是出了名的糟糕,因此依赖文档是确保调用者(或在调用者中编写代码的程序员)执行避免上述问题所需的操作的糟糕方法。

否,仅当没有传递给默认参数时才使用默认参数。new不会被调用,因此不会有内存分配。此外,正如一些程序员所说,如果你在函数体内部(或外部)的某个时候不清理,你就会有内存泄漏。

最新更新