在堆上分配内存还是传递工作内存?

Allocating memory on heap or passing work memory?

函数需要额外内存的情况相对经常发生。

在旧代码中,我经常遇到额外的 space 必须由调用者提供并作为工作数组传递给函数。我想这会给调用函数留下更多的灵活性,并可能提高性能。

另一方面,分配内存保证了内存的实际可用,也简化了界面。

是否有处理这些案例的最佳实践?

通常,如果您的函数需要一个长度未知且最大尺寸不小的数组,那么正确的处理方法是使用 newmalloc并在堆上分配内存。

举例来说,您需要解析一个文件并将其内容读入一个数组,而您不知道该文件的长度然后使用 vector<> 将是正确的方法。然后,当您调用 push_back() 时,您添加的元素会进入堆中的某处。

"Old" 我见过的要求调用者为工作数组分配内存的代码是在动态内存分配成为计算语言的标准部分之前编写的(或编写了其中的重要组成部分)。 (例如,参见 Fortran 77。)他们之所以不这样做,是因为他们认为这是很好的实践,因为计算机科学还没有发展到足够的程度。除非您出于遗留原因链接到这样的库,否则动态分配是更好的方法。

在 C 代码中,通常让调用者负责内存分配,例如strcpy。问题是被调用的函数不知道它实际可以使用多少内存。因此 C 有一些函数,调用者也可以指定最大值,例如strncpy.

在 C++ 中,如果需要,让被调用的函数处理内存分配是很常见的。例如vector::push_back。但是,C++ 仍然有调用者负责的函数,例如std::memcpy.

所以没有规则指定其中之一。但是,如果可能的话,最好让被调用的函数处理内存分配。

仍然存在调用者可以通过参与分配获得更好性能的情况。示例:您调用传递一个(对一个)向量的函数,被调用函数会将数据放入向量中。如果调用者知道将添加 (push_backed) 很多新元素并且调用者知道大概数量(例如 8000 到 10000),调用者可以通过在执行之前在向量中保留 10000 个条目来提高性能称呼。所以这就像一个共同的努力。但是被调用的函数仍然可以安全地处理需要超过 10000 个条目的情况。

"heap or passing work memory" 中,您提出了错误的二分法 - 到目前为止 最常见的做法是调用函数使用"working" 内存的堆栈。使用堆栈比动态分配更快,并且确保在执行离开变量的包含范围时重新分配,即使由于异常也是如此。

如果被调用函数正在为调用者准备 return 的值...那不仅仅是 "working" 内存,我认为这不是您要问的,但 FWIW在那种情况下,被调用者可能希望将内存与堆栈分离,以允许数据的生命周期超过它自己的生命周期。这通常是使用动态分配完成的,要么在 returning 标准库容器时隐式地完成,要么显式地使用 new(希望是共享指针)。