ความแตกต่างระหว่างใหม่ / ลบและ malloc / ฟรีคืออะไร?


283

ความแตกต่างระหว่างnew/ deleteและmalloc/ freeคืออะไร?

ที่เกี่ยวข้อง (ซ้ำกัน?): ฉันจะใช้ malloc กับ new ในกรณีใดบ้าง


ดูเพิ่มเติมคำตอบรายละเอียดของฉันที่นี่
Jonathan H

คำตอบ:


466

ใหม่ / ลบ

  • จัดสรร / ปล่อยหน่วยความจำ
    1. หน่วยความจำที่จัดสรรจาก 'ร้านค้าฟรี'
    2. ส่งคืนตัวชี้ที่พิมพ์อย่างสมบูรณ์
    3. ใหม่ (รุ่นมาตรฐาน) จะไม่ส่งคืน NULL (จะเกิดความล้มเหลว)
    4. ถูกเรียกด้วย Type-ID (คอมไพเลอร์คำนวณขนาด)
    5. มีเวอร์ชันอย่างชัดเจนเพื่อจัดการอาร์เรย์
    6. การจัดสรรใหม่ (เพื่อให้มีพื้นที่มากขึ้น) ไม่ได้รับการจัดการโดยสังหรณ์ใจ (เนื่องจากตัวสร้างสำเนา)
    7. ไม่ว่าพวกเขาจะเรียกใช้ malloc / free หรือไม่ก็ตาม
    8. สามารถเพิ่มตัวจัดสรรหน่วยความจำใหม่เพื่อจัดการกับหน่วยความจำเหลือน้อย (set_new_handler)
    9. ผู้ประกอบการใหม่ / ลบสามารถถูกแทนที่ตามกฎหมาย
    10. ตัวสร้าง / destructor ที่ใช้ในการเริ่มต้น / ทำลายวัตถุ

malloc / ฟรี

  • จัดสรร / ปล่อยหน่วยความจำ
    1. หน่วยความจำที่จัดสรรจาก 'ฮีป'
    2. ส่งคืนช่องว่าง *
    3. ส่งคืน NULL เมื่อเกิดความล้มเหลว
    4. ต้องระบุขนาดที่ต้องการในหน่วยไบต์
    5. การจัดสรรอาร์เรย์ต้องการการคำนวณพื้นที่ด้วยตนเอง
    6. จัดสรรหน่วยความจำขนาดใหญ่ได้ง่าย ๆ (ไม่มีตัวสร้างสำเนาที่ต้องกังวล)
    7. พวกเขาจะไม่เรียกใหม่ / ลบ
    8. ไม่มีวิธีการประกบรหัสผู้ใช้ในลำดับการจัดสรรเพื่อช่วยในหน่วยความจำเหลือน้อย
    9. malloc / free ไม่สามารถเขียนทับได้อย่างถูกกฎหมาย

ตารางเปรียบเทียบคุณสมบัติ:

 Feature                  | new/delete                     | malloc/free                   
--------------------------+--------------------------------+-------------------------------
 Memory allocated from    | 'Free Store'                   | 'Heap'                        
 Returns                  | Fully typed pointer            | void*                         
 On failure               | Throws (never returns NULL)    | Returns NULL                  
 Required size            | Calculated by compiler         | Must be specified in bytes    
 Handling arrays          | Has an explicit version        | Requires manual calculations  
 Reallocating             | Not handled intuitively        | Simple (no copy constructor)  
 Call of reverse          | Implementation defined         | No                            
 Low memory cases         | Can add a new memory allocator | Not handled by user code      
 Overridable              | Yes                            | No                            
 Use of (con-)/destructor | Yes                            | No                            

หน่วยความจำทางเทคนิคที่จัดสรรโดยใหม่มาจาก 'Free Store' ในขณะที่หน่วยความจำที่จัดสรรโดย malloc มาจาก 'Heap' ไม่ว่าทั้งสองพื้นที่จะเหมือนกันหรือไม่เป็นรายละเอียดการใช้งานซึ่งเป็นอีกเหตุผลหนึ่งที่ malloc และใหม่ไม่สามารถผสมกันได้


12
ใครสามารถแก้ไขรายละเอียดเกี่ยวกับ "ร้านค้าฟรี" เมื่อเทียบกับกอง? ฮีปของกระบวนการเป็นแนวคิดระบบปฏิบัติการระดับภาษาที่รู้จักกันดี (?); "ร้านค้าฟรี" มาจากไหน
einpoklum

1
@einpoklum: พวกเขาเป็นเพียงชื่อของพื้นที่หน่วยความจำ ไม่มีอะไรเกี่ยวข้องกับแนวคิดภาษาที่เรียกว่า "ฮีป" หรือแนวคิดระบบปฏิบัติการของ "ฮีปกระบวนการ" C ++ ได้รับการกำหนดอย่างตั้งใจให้เป็นแพลตฟอร์ม / OS / คอมไพเลอร์กลาง ดังนั้นการใช้แนวคิดระบบปฏิบัติการเฉพาะเช่น "กระบวนการฮีป" จะบ่อนทำลายความยืดหยุ่นของมาตรฐาน
Martin York

4
@winterlight: ที่เคยเป็นจริง แต่ไม่อีกต่อไป ดู: linux.die.net/man/3/free If ptr is NULL, no operation is performed.
Martin York

2
@ LokiAstari ดูเหมือน 'heap', 'free store' และ 'memory memory / storage' เป็นคำพ้องความหมาย: ในA Tour of C ++ ของ Bjarne Stroustrup เขากล่าวว่า " newผู้ดำเนินการจัดสรรหน่วยความจำจากร้านค้าฟรี (หรือที่เรียกว่าหน่วยความจำแบบไดนามิกและฮีป ) มาตรฐาน C ++ 14 ส่วน 3.7.4 บนDynamic Storageกล่าวว่า "สามารถสร้างวัตถุแบบไดนามิกระหว่างการทำงานของโปรแกรม (1.9) โดยใช้นิพจน์ใหม่ (5.3.4) และทำลายโดยใช้นิพจน์ลบ"
สูงสุด Heiber

2
@ mhiber: มันหมายความว่าพวกเขาสามารถเหมือนกัน และการใช้งานหลาย ๆ ตัวใช้งานใหม่โดยการเรียก malloc (หมายเหตุวิธีอื่น ๆ ไม่ได้รับอนุญาต) แต่การใช้งานหลายครั้งทำให้พื้นที่หน่วยความจำเหล่านั้นแยกจากกัน เหตุผลที่แยกเก็บไว้เช่นกันคือสิ่งนี้ทำให้รหัสการจัดการหน่วยความจำ C ++ ได้รับการปรับให้เหมาะสมในวิธีที่แตกต่างจากการจัดการหน่วยความจำ C ประเด็นคือ: พวกเขาอาจจะเหมือนกัน แต่คุณไม่สามารถคิดได้ว่าพวกเขาเป็น
Martin York

81

ความแตกต่างที่เกี่ยวข้องมากที่สุดคือnewผู้ประกอบการจัดสรรหน่วยความจำจากนั้นเรียกตัวสร้างและdeleteเรียก destructor แล้วจัดสรรหน่วยความจำ


22
พูดอย่างเคร่งครัดผู้ประกอบการใหม่เพียงจัดสรรหน่วยความจำ มันเป็นนิพจน์ใหม่ที่เรียกผู้ประกอบการใหม่แล้วเรียกใช้ตัวสร้างในหน่วยความจำที่จัดสรร
Don Wakefield

ความแตกต่างก็คือที่จัดสรรหน่วยความจำ ฉันเพิ่งเห็นบางแห่งที่ malloc / free ทำงานบน heap ขณะที่ new / delete ทำงานในพื้นที่หน่วยความจำอื่นที่มีชื่อฉันตอนนี้ (พอจะพูดได้ว่าพื้นที่อื่น ๆ สามารถอาจจะคิดว่าเป็นกองอื่น.)
RobH

2
@mgb: ใช่แล้วคุณถูกต้องแล้วว่ามีการจัดสรรออบเจ็กต์ใน "Application heap" หรือ stack แต่ @RobH หมายถึงสิ่งที่มาตรฐานเรียกว่าส่วนต่าง ๆ ของ "Application Heap" มี "ฮีป" ซึ่งเป็นที่ซึ่ง malloc จัดสรรหน่วยความจำจากและ "Free Store" ซึ่งมีการจัดสรรหน่วยความจำใหม่ แม้ว่าในบางการใช้งานพื้นที่เหล่านี้จะทับซ้อนกัน (นี่คือรายละเอียดการใช้งาน)
Martin York

1
ใบแจ้งยอดของคุณถูกต้อง 100% แต่ไม่ตอบคำถามที่ถามดูคำตอบด้านล่างมีเหตุผลว่าทำไมคะแนนมากกว่าของคุณ
Murali

1
ทั้งหมดที่ฉันพยายามจะพูดคือควรมีอย่างน้อยพูดถึง malloc / ฟรีเพื่อให้มีคุณสมบัติเป็นการเปรียบเทียบที่คำตอบของคุณขาด อย่างไรก็ตามมันเป็นคำที่เกี่ยวข้องและถูกต้องดังนั้น upvotes ฉันหวังว่าคุณจะเข้าใจจุดของฉัน อย่างไรก็ตามถ้าเพียงแค่อนุญาตให้ฉันไปลงคะแนนของฉันฉันจะสุดใจ
Murali

30

newเรียก ctor ของวัตถุdeleteเรียก dtor

malloc& freeจัดสรรและปล่อยหน่วยความจำดิบ


คุณหมายถึงอะไรโดยความทรงจำดิบ?
Destructor

3
หน่วยความจำดิบไม่มีอะไรทำ ยังไม่มีการสร้างวัตถุในนั้นยังไม่มีการคัดลอกลงในและในกรณีส่วนใหญ่เนื้อหาก่อนหน้านี้ยังไม่ได้ถูกเขียนทับ
James Curran

14

new/ deleteคือ C ++, malloc/ freeมาจาก C เก่าที่ดี

ใน C ++ newเรียกใช้ตัวสร้างวัตถุและdeleteเรียก destructor

mallocและfreeมาจากยุคมืดก่อน OO เท่านั้นจัดสรรและเพิ่มหน่วยความจำโดยไม่ต้องใช้รหัสของวัตถุใด ๆ


9
"มาจากยุคมืดก่อน OO" ดูเหมือนว่าคุณหมายถึงว่าใหม่ / ลบดีกว่า malloc / ฟรีเมื่อในความเป็นจริงไม่ดีหรือแย่กว่าพวกเขามีการใช้ที่แตกต่างกัน โปรดทราบว่าฉันไม่ใช่คนที่ลงคะแนนคุณฉันแค่เดา
แกรมเพอร์โรว์

13

ใน C ++ new/ deleteเรียก Constructor / Destructor ตามลำดับ

malloc/ freeเพียงจัดสรรหน่วยความจำจากฮีป new/ deleteจัดสรรหน่วยความจำเช่นกัน


10

ความคล้ายคลึงกันเพียงอย่างเดียวคือmalloc/ newทั้งคู่ส่งคืนตัวชี้ซึ่งระบุถึงหน่วยความจำบางส่วนบนฮีปและทั้งคู่รับประกันว่าเมื่อมีการส่งคืนบล็อกหน่วยความจำดังกล่าวแล้วจะไม่ถูกส่งคืนอีกเว้นแต่คุณจะว่าง / ลบก่อน นั่นคือพวกเขาทั้งสอง "จัดสรร" หน่วยความจำ

อย่างไรก็ตามnew/ deleteทำงานโดยพลการอื่นนอกจากนี้ผ่านทางตัวสร้าง destructors และตัวดำเนินการมากเกินไป malloc/ freeเท่านั้นที่เคยจัดสรรและเพิ่มหน่วยความจำ

ในความเป็นจริงnewสามารถปรับแต่งได้อย่างเพียงพอซึ่งไม่จำเป็นต้องส่งคืนหน่วยความจำจากฮีปหรือแม้แต่จัดสรรหน่วยความจำเลย อย่างไรก็ตามค่าเริ่มต้นnewไม่


7

ความแตกต่างที่สำคัญระหว่าง new และ malloc ก็คือ new จะเรียกใช้ตัวสร้างของวัตถุและการเรียกที่สอดคล้องกันเพื่อลบ invokes destructor ของวัตถุ

มีความแตกต่างอื่น ๆ :

  • newเป็นประเภทที่ปลอดภัยmallocส่งกลับวัตถุประเภทvoid*

  • newโยนข้อยกเว้นในข้อผิดพลาดmallocผลตอบแทนNULLและการตั้งค่า errno

  • newเป็นโอเปอเรเตอร์และสามารถโอเวอร์โหลดmallocได้เป็นฟังก์ชั่นและไม่สามารถโอเวอร์โหลดได้

  • new[]ซึ่งจัดสรรอาเรย์นั้นง่ายกว่าและปลอดภัยกว่าประเภทอื่น ๆ malloc

  • malloc- การปันส่วนที่ได้รับมาสามารถปรับขนาดผ่านrealloc- การnewปันส่วนที่ได้รับไม่สามารถปรับขนาดได้

  • mallocสามารถจัดสรรหน่วยความจำแบบ N-byte ได้, newต้องทำการจัดสรรอาเรย์, charประเภท, ประเภท

เมื่อดูที่ความแตกต่างสรุปคือ malloc คือ C-esque ใหม่คือ C ++ - esque ใช้อันที่เหมาะกับฐานรหัสของคุณ

แม้ว่ามันจะถูกกฎหมายสำหรับใหม่และ malloc ที่จะดำเนินการโดยใช้อัลกอริทึมการจัดสรรหน่วยความจำที่แตกต่างกันในระบบใหม่ส่วนใหญ่จะดำเนินการภายในโดยใช้ malloc ทำให้ไม่มีความแตกต่างในระดับระบบ


5

มีบางสิ่งที่newทำmallocไม่ได้:

  1. new สร้างวัตถุโดยการเรียกตัวสร้างของวัตถุนั้น
  2. new ไม่จำเป็นต้องพิมพ์หน่วยความจำที่จัดสรร
  3. ไม่จำเป็นต้องจัดสรรจำนวนหน่วยความจำ แต่ต้องการจำนวนวัตถุที่จะสร้าง

ดังนั้นถ้าคุณใช้mallocคุณต้องทำสิ่งต่าง ๆ อย่างชัดเจนซึ่งไม่สามารถนำไปใช้ได้จริงเสมอไป นอกจากนี้newสามารถโอเวอร์โหลดได้ แต่mallocไม่สามารถ

ในคำถ้าคุณใช้ C ++ ลองใช้newให้มากที่สุด


4

นอกจากนี้ยังมี

ใหม่ทั่วโลกและลบสามารถแทนที่, malloc / ฟรีไม่สามารถ

เพิ่มเติมใหม่และลบสามารถแทนที่ต่อประเภท


3

newและdeleteเป็น C + + แบบดั้งเดิมซึ่งประกาศอินสแตนซ์ใหม่ของคลาสหรือลบมัน (เช่นการเรียกใช้ destructor ของคลาสสำหรับอินสแตนซ์)

mallocและfreeเป็นฟังก์ชั่น C และจะจัดสรรและเพิ่มบล็อกหน่วยความจำ (ขนาด)

ทั้งสองใช้ฮีปเพื่อทำการจัดสรร mallocและfreeยังคง "ระดับต่ำ" มากขึ้นตามที่พวกเขาเพียงแค่สำรองพื้นที่หน่วยความจำซึ่งอาจจะเกี่ยวข้องกับตัวชี้ ไม่มีโครงสร้างใดถูกสร้างขึ้นรอบ ๆ หน่วยความจำนั้น (เว้นแต่คุณจะถือว่าอาร์เรย์ C เป็นโครงสร้าง)


1
ใหม่ใน C ++ ไม่ได้ประกาศอินสแตนซ์ของคลาส มัน (ปกติ) จัดสรรหนึ่งค่าจากกองและมันไม่ได้ประกาศอะไรเลย คุณสามารถประกาศอินสแตนซ์เพียงแค่ประกาศมันซึ่งในกรณีนี้มันจะอยู่ในสแต็กหรือในรูปกลมขึ้นอยู่กับระยะเวลาการจัดเก็บของการประกาศ
Steve Jessop

มันจัดสรรพื้นที่หน่วยความจำสำหรับคลาส แต่คุณไม่สามารถ "ประกาศ" คลาสในสแต็กไม่ใช่ในความหมายที่แท้จริงของการจัดเก็บคลาสในสแต็ก การประกาศเกี่ยวข้องกับเพียงตัวชี้ไปยังคลาสซึ่งถูกจัดสรรในสแต็กเสมอหน่วยความจำจริงที่เก็บคลาสอยู่ในฮีป
Jorge Córdoba

ใช่คุณสามารถ. ตามแท็กคำถามนี่คือ C ++ ดังนั้นวัตถุสามารถอยู่ในกองซ้อนได้ และใหม่ไม่ใช่การประกาศมันเป็นการแสดงออก ประกาศบางสิ่งบางอย่างและจัดสรรเป็นสิ่งแยกจากกัน
Steve Jessop

2

ใหม่และลบเป็นตัวดำเนินการใน c ++; ซึ่งสามารถโอเวอร์โหลดได้เช่นกัน malloc และ free เป็นฟังก์ชันใน c;

malloc ส่งคืน null ptr เมื่อล้มเหลวในขณะที่มีข้อผิดพลาดเกิดขึ้นใหม่

ที่อยู่ที่ถูกส่งกลับโดย malloc ต้องตามประเภท casted อีกครั้งเนื่องจากส่งคืน (void *) malloc (ขนาด) ใหม่ส่งคืนตัวชี้ที่พิมพ์


2
  • ใหม่เป็นผู้ประกอบการในขณะที่ malloc () เป็น fucntion
  • ใหม่ส่งคืนชนิดข้อมูลที่แน่นอนในขณะที่ malloc () จะคืนค่าเป็นโมฆะ * (ตัวชี้ประเภทเป็นโมฆะ)
  • malloc () หน่วยความจำไม่ได้เริ่มต้นและค่าเริ่มต้นเป็นขยะในขณะที่ในกรณีของใหม่หน่วยความจำจะเริ่มต้นด้วยค่าเริ่มต้นเช่นกับ 'ศูนย์ (0)' ในกรณีที่ int
  • ลบและฟรี () ทั้งสองสามารถใช้สำหรับตัวชี้ 'NULL'

0
  • เมื่อต้องการใช้malloc()เราต้องรวม <stdlib.h>หรือ ในโปรแกรมที่ไม่จำเป็นสำหรับ<alloc.h>new
  • newและdeleteสามารถโอเวอร์โหลดได้ แต่mallocไม่สามารถทำได้
  • การใช้ตำแหน่งnewที่เราสามารถส่งอยู่ที่เราต้องการที่จะจัดสรรหน่วยความจำ mallocแต่เรื่องนี้เป็นไปไม่ได้ในกรณีของ

1
alloc.hไม่ใช่ส่วนหัวมาตรฐาน <new>จำเป็นต้องใช้ตำแหน่งใหม่
MM

0

รหัสนี้ใช้สำหรับลบคำสำคัญหรือฟังก์ชั่นฟรี แต่เมื่อสร้างวัตถุตัวชี้โดยใช้ 'malloc' หรือ 'ใหม่' และ deallocate หน่วยความจำวัตถุโดยใช้การลบแม้ตัวชี้วัตถุที่สามารถเรียกใช้ฟังก์ชั่นในชั้นเรียน หลังจากนั้นใช้ฟรีแทนการลบแล้วมันยังทำงานหลังจากคำสั่งฟรี แต่เมื่อใช้ทั้งสองแล้ววัตถุตัวชี้เท่านั้นที่ไม่สามารถเรียกใช้ฟังก์ชั่นในระดับ .. รหัสมีดังนี้:

#include<iostream>


using namespace std;

class ABC{
public: ABC(){
    cout<<"Hello"<<endl;
  }

  void disp(){
    cout<<"Hi\n";
  }

};

int main(){

ABC* b=(ABC*)malloc(sizeof(ABC));
int* q = new int[20];
ABC *a=new ABC();
b->disp();

cout<<b<<endl;
free(b);
delete b;
//a=NULL;
b->disp();
ABC();
cout<<b;
return 0;
}

ผลลัพธ์:

Hello
Hi
0x2abfef37cc20

-3

1. syntex ใหม่นั้นง่ายกว่า malloc ()

2.new/delete เป็นโอเปอเรเตอร์ที่ malloc () / free () เป็นฟังก์ชั่น

3.new/delete รันเร็วกว่า malloc () / free () เนื่องจากโค้ด assemly ใหม่วางโดยตรงโดยคอมไพเลอร์

4. เราสามารถเปลี่ยนใหม่ / ลบความหมายในโปรแกรมด้วยความช่วยเหลือของผู้ประกอบการที่ทับซ้อนกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.