电子产业一站式赋能平台

PCB联盟网

搜索
查看: 191|回复: 0
收起左侧

C++中还需要使用malloc吗?

[复制链接]

1001

主题

1001

帖子

8805

积分

高级会员

Rank: 5Rank: 5

积分
8805
发表于 2024-12-5 08:00:00 | 显示全部楼层 |阅读模式

kooafssll5j64066433251.gif

kooafssll5j64066433251.gif
6 ^! }) r7 H2 O/ N
点击上方蓝色字体,关注我们) D5 w; F5 m) |3 l8 d& f
new 与智能指针提供了类型安全、自动管理内存等优点,能够更好地满足大多数场景的需求。9 J$ ^" m0 D/ n7 \# P
11 |1 ]  t1 L3 S$ o% T% Z$ H
malloc 和 new 的区别
% C0 x! S* j) p1 Z$ l  g% z7 @  Ymalloc 是 C 语言的内存分配函数,分配的内存是未初始化的,并返回 void* 类型的指针。
; o/ s3 y% I" \7 p% m8 I' j7 ?( G2 M0 I( w0 W- e3 S' [0 @
要想将 malloc 的返回值赋给特定类型的指针,需要进行显式类型转换,这就缺乏类型安全性。
) q5 b/ E+ a' s/ F6 h) b
- y0 X! S: |* X, c! R) [  I. {而 C++ 的 new 操作符会自动调用构造函数,并返回指定类型的指针,避免了类型转换问题,增加了类型安全性。! e5 d9 o, t* Z4 I8 w  y
8 ]+ f& B; K! c! t- M8 X, w' K6 }
new 不仅分配内存,还会调用类的构造函数来初始化对象。而 malloc 仅分配内存,不做初始化。7 `+ R( s, [& M% D" Z# H7 e% q
* }% y! H  B/ m' |
这意味着使用 malloc 时,我们无法直接管理对象的生命周期,必须手动调用构造函数和析构函数(这几乎不常见且容易出错)。
& ]9 V* }2 w" F$ |3 j2+ t! e) ^! Z/ U2 c5 m: ~, q( u# H
智能指针和现代 C++ 内存管理# t- W+ D( p5 U6 ]$ S) C  C
C++11 引入了智能指针,如 std::unique_ptr 和 std::shared_ptr,它们通过 RAII(Resource Acquisition Is Initialization)机制帮助自动管理内存。2 `4 s# P3 {' a4 h; M

& l) {* D9 J) \/ j这让开发者几乎不需要直接调用 new 或 delete,大幅降低了内存泄漏的风险。更不用说 malloc 和 free 了。
2 u! C# q+ o0 X- Y3 X3 ]2 t5 D+ T' e, C- k) s" i+ T
例如:
3 b' L, H+ g- }/ ~; N/ M. P1 d5 Y. ]5 D% j9 ^8 k
  • std::unique_ptrptr = std::make_unique(10);  // 自动管理内存
    9 v% c$ w2 h$ l$ s$ u: G2 p使用智能指针,内存会在指针超出作用域时自动释放,无需手动调用 free。
    $ h( e/ g% r( B& c/ ?3$ ?) i5 i0 C: w
    使用 malloc 的场景0 f  N% O7 p% ^5 v- H
    尽管现代 C++ 提供了更好的内存管理工具,但在少数特定场景下,malloc 仍然可能有其用武之地。
    0 R* I- ~* b. z4 f
    - E; d- G$ P) k/ t; d如果你需要与大量 C 代码或使用 C 库的项目协作(如某些底层嵌入式系统开发),使用 malloc 会更容易实现与 C 代码的无缝交互。6 b$ {) o$ A: i. P/ j
    0 }* a: A7 t5 j7 ~. W
    在某些性能要求极高的系统中,为了精细控制内存布局和管理,开发者可能会实现自定义的内存分配器。/ `; B6 y2 u# h& o8 f7 S
    / P7 M3 p4 d& I4 {! F
    自定义分配器的内部实现可能基于 malloc 这种低级分配函数,以便更灵活地优化内存操作。6 f; _$ I& z  I- @6 ]- y1 C# i
    / K, ~6 q4 c. K6 D; g& |( }3 s, U
    不需要构造函数的分配:对于不需要初始化的原始数据块或 POD(Plain Old Data)类型数据,malloc 有时可能更加直接,比如用于分配一个不需要构造和析构的字节缓冲区。# w8 p! ]. p0 _( ~
    4$ ^8 ^" `! J. O- w& h
    实际代码示例
    5 d$ q3 _- c# r- h% [4 }7 WC++ 的方式' s+ p3 H+ u% x: t8 ~1 e
  • struct MyClass {    MyClass() { std::cout "Constructed$ a, A. o+ Q5 v3 M' l
    "; }    ~MyClass() { std::cout "Destructed9 b- ^; s$ w# C
    "; }};; c' x2 d8 X& x# h7 @
    int main() {    auto ptr = std::make_unique();  // 自动调用构造/析构}
    * z4 r$ d# a5 F' m: \. `8 N使用 malloc 的方式(不推荐,除非必须兼容 C)8 {  F9 q" a* \  r' J! s
  • struct MyClass {    MyClass() { std::cout "Constructed
    . X! Z0 a, g$ P4 W3 Y+ }! r# q, C  M"; }    ~MyClass() { std::cout "Destructed
    7 e# y+ y# _/ }! s2 Z"; }};" i% \* N* E, q9 N, A3 D
    int main() {    MyClass* ptr = (MyClass*)malloc(sizeof(MyClass));    new(ptr) MyClass;   // 手动调用构造函数    ptr->~MyClass();    // 手动调用析构函数    free(ptr);}
      u0 E7 M5 D& b8 p6 |在第二种方式中,手动管理构造和析构显得繁琐且不直观,容易引入内存泄漏或未定义行为。0 \2 h0 g* J4 z

    u33aa4nltj464066433351.jpg

    u33aa4nltj464066433351.jpg
    " O% u% j" C% f# H% I! {# {$ D4 ]

    4kkspejwcgh64066433451.gif

    4kkspejwcgh64066433451.gif

    3 U% M$ g  K2 U6 W: g点击阅读原文,更精彩~
  • 回复

    使用道具 举报

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则


    联系客服 关注微信 下载APP 返回顶部 返回列表