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

时间:2015-08-21 05:32:14

标签: c++ c memory memory-management coding-style

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

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

另一方面,分配内存可确保内存实际可用,并简化界面。

是否有类似处理这些案件的最佳做法?

4 个答案:

答案 0 :(得分:2)

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

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

因此没有规则指定其中一个。但是,如果可能的话,让被调用的函数处理内存分配似乎是最好的实践。

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

答案 1 :(得分:1)

"旧"在动态内存分配是计算语言的标准部分之前,我已经看到了需要调用者为工作数组分配内存的代码(或者编写了它们的重要组件)。 (例如,参见Fortran 77.)他们没有这样做,因为他们认为这是一种很好的做法,因为计算机科学还没有进化到足够远的程度。除非您因遗留原因而链接到此类库,否则动态分配是更好的方法。

答案 2 :(得分:0)

通常,如果你的函数需要一个你不知道且长度不小的数组,那么正确的方法是使用newmalloc并分配堆上的内存。

比如说你需要解析一个文件并将其内容读入一个数组,你不知道该文件有多长,然后使用vector<>将是正确的方法。然后当你调用push_back()时,你添加的元素就会出现在堆上的某个地方。

答案 3 :(得分:0)

“堆或传递工作内存”中你提出了一个错误的二分法 - 到目前为止最常见的做法是被调用的函数使用堆栈来“工作” “记忆。使用堆栈比动态分配更快,并确保在执行离开变量包含范围时释放,即使是由于异常。

如果被调用的函数正在准备一个返回调用者的值...那不仅仅是“工作”内存而且我认为这不是你所要求的,但是在那种情况下被调用者可能希望将内存与堆栈分离,以使数据的生命周期长于自己的生命周期。这通常是使用动态分配完成的,可以在返回标准库容器时隐式执行,也可以使用new显式执行(希望是共享指针)。