实际上,该函数不会返回ints 的数组(即int[N])。它返回的是一个指向int (int *) 的指针。事实证明,这个指针指向 s 类型为 int 的元素数组的第一个元素。
注意内存是用new分配的:
int *ret = new int[s];
因此ret指向的ints数组具有动态存储时长。除其他外,这意味着
1) 编译器不会自动调用每个数组元素的析构函数。 (在这种情况下,这不是问题,因为元素的类型是 int,但如果元素是具有非平凡析构函数的类类型,则可能是 where。)
2) 编译器不会自动释放分配的内存。
相比之下,请考虑以下代码:
void g() {
int p[10]; // allocates 10 integer in the stack
// use p ...
}
当g 终止时,编译器将执行上述操作。为此,必须在编译时设置数组的大小(本例中为 10)。如果您在编译时不知道大小,则需要new,如原始代码中所示。
对于动态分配的数组,程序员有责任确保在不再需要数组时执行上述两个操作。为此,您必须致电delete[]:
delete[] p; // where p is a `int*` with the same value as `ret`
在实践中,这比看起来更困难,因为有可能
抛出异常。例如,考虑这段代码
void foo() {
int* p = f(10); // where f is in the question
// ... use the array pointed by p
a_function_that_might_throw();
delete[] p;
}
如果a_function_that_might_throw 确实抛出异常,则执行
永远不会达到删除p 的地步。在这种情况下,内存
由new 分配的(在f 内部)将不会被释放(它泄漏),直到
程序终止。
为了避免这个问题,最好不要使用原始指针(例如int*)
使用智能指针(例如 std::unique_ptr 或 std::shared_ptr)。
最后,默认情况下new分配的内存是堆内存。然而,
你可以改变这种行为。