马洛克vs新的原始人
我明白在C ++中使用new
对malloc
的好处。 但对于诸如基本数据类型(非数组)的特定情况( int
, float
等),使用malloc
比使用new
更快吗?
尽管如此,即使对基元使用new
也是可取的,如果我们正在分配一个数组,以便我们可以使用delete[]
。
但对于非数组分配,我认为不会有任何构造函数调用int
? 因为, new
运算符分配内存,检查它是否被分配,然后调用构造函数。 但是对于原语非数组堆分配,使用malloc
比new
更好吗?
请指教。
切勿在C ++中使用malloc
。 除非您正在实施低级内存管理原语,否则请勿使用new
内存
建议是:
问问自己:“我需要动态内存分配吗?”。 很多时候你可能不需要它 - 比较喜欢指针的值 ,并尝试使用堆栈。
如果您确实需要动态内存分配,请问自己“谁将拥有分配的内存/对象?”。
如果你只需要一个所有者(很可能),你应该使用std::unique_ptr
。 这是对new
/ delete
的零成本抽象。 (可以指定不同的释放器。)
如果你需要共享所有权,你应该使用std::shared_ptr
。 这不是零成本抽象,因为它使用原子操作和一个额外的“控制块”来跟踪所有的所有者。
如果特别处理数组,标准库提供了两个强大且安全的抽象,不需要任何手动内存管理:
std::array<T, N>
:一个T
类型的N
元素的固定数组。
std::vector<T>
类型的元件的可调整大小的阵列T
。
std::array
和std::vector
应该覆盖99%的“数组需求”。
还有一件重要的事情:标准库提供了std::make_unique
和std::make_shared
,它们应该总是用来创建智能指针实例。 有几个很好的理由:
更短 - 无需重复T
(例如std::unique_ptr<T>{new T}
),不需要使用new
。
更多的异常安全。 它们可以防止由于在函数调用中缺少明确定义的评估顺序而导致潜在的内存泄漏。 例如
f(std::shared_ptr<int>(new int(42)), g())
可以按以下顺序评估:
new int(42)
g()
如果g()
抛出,则int
被泄漏。
更高效(就运行速度而言)。 这只适用于std::make_shared
- 直接使用它而不是std::shared_ptr
允许实现为对象和控制块执行单个分配。
你可以在这个问题中找到更多信息。
在与使用纯C指定的API进行交互时,仍然有必要使用malloc
和C ++ free
,因为不保证使用free
来释放分配给operator new
内存是安全的(这最终是所有被管理的内存类使用),也不使用operator delete
来释放分配给malloc
。
一个典型的例子是POSIX getline
(不要和std::getline
混淆):它需要一个指向char *
变量的指针; 该变量必须指向用malloc
分配的内存块(或者它可以为NULL,在这种情况下, getline
将为您调用malloc
); 当你完成调用getline
你需要在该变量上free
地调用。
同样,如果你正在编写一个库,那么在内部使用C ++是有意义的,但为你的外部调用者定义一个extern "C"
API,因为它给你提供了更好的二进制接口稳定性和跨语言互操作性。 如果你返回堆分配POD对象,您的呼叫,您可能希望让他们收回与这些对象free
; 他们不一定使用delete
,并且当没有析构函数类型的操作需要是无人YourLibraryFree
时候,让他们调用YourLibraryFree。
在实现可调整大小的容器对象时,还可能需要使用malloc
,因为对于operator new
没有等价的realloc
。
但正如其他答案所说,当你没有这种接口约束绑定你的手时,请使用一个托管内存类。
使用new
的总是更好。 如果你使用malloc
你仍然需要手动检查空间是否分配。
在现代c ++中,你可以使用智能指针。 使用make_unique
和make_shared
你永远不会明确地调用new
。 std::unique_ptr
不大于底层指针,使用它的开销很小。