new / deleteとmalloc / freeの違いは何ですか?


回答:


465

新規/削除

  • メモリの割り当て/解放
    1. 「フリーストア」から割り当てられたメモリ
    2. 完全に型指定されたポインタを返します。
    3. 新しい(標準バージョン)は決してNULLを返しません(失敗するとスローされます)
    4. Type-IDで呼び出されます(コンパイラーがサイズを計算します)
    5. 配列を明示的に処理するバージョンがあります。
    6. (より多くのスペースを得るために)再割り当ては直感的に処理されません(コピーコンストラクターのため)
    7. malloc / freeを呼び出すかどうかは、実装によって定義されます。
    8. メモリ不足に対処するために新しいメモリアロケータを追加できます(set_new_handler)
    9. オペレーターの新規/削除は合法的にオーバーライドできます
    10. オブジェクトの初期化/破棄に使用されるコンストラクタ/デストラクタ

malloc / free

  • メモリの割り当て/解放
    1. 「ヒープ」から割り当てられたメモリ
    2. void *を返します
    3. 失敗するとNULLを返します
    4. 必要なサイズをバイト単位で指定する必要があります。
    5. 配列を割り当てるには、手動でスペースを計算する必要があります。
    6. 単純なメモリの大きなチャンクの再割り当て(心配するコピーコンストラクターはありません)
    7. 彼らはnew / deleteを呼び出しません
    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                            

技術的には、newによって割り当てられたメモリは「フリーストア」から、mallocによって割り当てられたメモリは「ヒープ」から取得されます。これら2つの領域が同じであるかどうかは、実装の詳細です。これが、mallocとnewを混合できないもう1つの理由です。


12
ヒープとは対照的に、誰かが「無料ストア」について詳しく説明するために編集できますか?プロセスのヒープは、よく知られている言語に依存しない(?)オペレーティングシステムレベルの概念です。「フリーストア」はどこから来たのですか?
einpoklum 2016

1
@einpoklum:これらは単なるメモリ領域の名前です。「ヒープ」と呼ばれる言語の概念や「プロセスヒープ」のosの概念とは何の関係もありません。C ++は、プラットフォーム/ OS /コンパイラに中立であると意図的に定義されています。したがって、「プロセスヒープ」などの特定のOSの概念を使用すると、標準の柔軟性が損なわれます。
マーティンヨーク

4
@winterlight:かつては真実でしたが、もはやそうではありませんでした。参照:linux.die.net/man/3/free If ptr is NULL, no operation is performed.
Martin York

2
@LokiAstari「ヒープ」、「フリーストア」、「ダイナミックメモリ/ストレージ」は同義語のように見えます:Bj​​arne StroustrupのA Tour of C ++では、「newオペレーターはフリーストアからメモリを割り当てます(ダイナミックメモリとしても知られています)そして、ヒープ)ザ・C ++ 14標準、上のセクション3.7.4。ダイナミックストレージは、「オブジェクトが新表現(5.3.4)を使用して、プログラムの実行(1.9)中に動的に作成、および削除式を使用して破壊することができます。」と言う
マックスハイバー

2
@mheiber:同じであることを意味します。そして、いくつかの実装はmallocを呼び出すことによってnewを実装します(他の方法は明示的に許可されていないことに注意してください)。しかし、いくつかの実装では、これらのメモリ領域を完全に分離しています。それらを別々に保った理由は、これによりC ++メモリ管理コードをCメモリ管理とは異なる方法で最適化できるためです。ポイントは次のとおりです。それらは同じである可能性がありますが、それらが同じであると想定することはできません。
マーティンヨーク

81

最も重要な違いは、new演算子がメモリを割り当ててからコンストラクタをdelete呼び出し、デストラクタを呼び出してメモリの割り当てを解除することです。


22
厳密に言えば、新しい演算子はメモリを割り当てるだけです。新しい演算子を呼び出して、割り当てられたメモリでコンストラクタを実行するのは、新しい式です。
Don Wakefield、

もう1つの違いは、メモリが割り当てられる場所です。私は最近、malloc / freeがヒープ上で動作するところを見つけましたが、new / deleteは、名前がわからない別のメモリ領域で動作します。(ただし、他の領域は別のヒープと
見なす

2
@mgb:はい、オブジェクトが「アプリケーションヒープ」またはスタックに割り当てられていることは正しいです。しかし、 @ RobHは、標準が「アプリケーションヒープ」のさまざまな部分と呼んでいるものを参照しています。mallocがメモリを割り当てる「ヒープ」と、newがメモリを割り当てる「フリーストア」があります。ただし、一部の実装ではこれらの領域が重複しています(これは実装の詳細です)。
マーティンヨーク

1
あなたの発言は100%正しいですが、尋ねられた質問には答えません。下の答えを見てください。あなたの票よりも投票数が多いのには理由があります。
Murali

1
私が言おうとしていたのは、malloc / freeを少なくともいくつか言及して、それが比較対象となるためにあなたの答えが欠けていたということだけでした。それでも、それは関連性があり正確な声明なので、賛成票は私の要点を理解していただければ幸いです。とにかく、もし私が私の反対投票を取り消すことを私に許しただけなら、私は心をこめてそうしました。
Murali、2010年

30

newオブジェクトdeleteのctorを呼び出し、dtorを呼び出します。

mallocfreeそのままのメモリを割り当てて解放します。


生のメモリとはどういう意味ですか?
デストラクタ

3
生のメモリは何も行われていません。オブジェクトはまだ作成されておらず、何もコピーされていません。ほとんどの場合、以前の内容は上書きされていません。
James Curran

14

new/ deleteはC ++であり、malloc/ freeは古き良きCに由来します。

C ++では、newオブジェクトコンストラクターをdelete呼び出し、デストラクターを呼び出します。

mallocそしてfree、OO前暗黒年代からの、唯一のオブジェクトの任意のコードを実行することなく、メモリを割り当て、解放します。


9
「OOの前の暗黒時代から来ている」というのは、実際のところ、どちらかが異なるだけで、new / deleteがmalloc / free より優れていることを暗示しているようです。私があなたに反対票を投じたわけではないことに注意してください。ただ推測しているだけです。
Graeme Perrow、

13

C ++ではnew/ delete適宜コンストラクタ/デストラクタを呼び出します。

malloc/ free単にヒープからメモリを割り当てます。new/ deleteメモリも割り当てます。


10

唯一の類似点はそれですmalloc/new両方がヒープ上の一部のメモリをアドレス指定するポインタを返すことであり、どちらも、このようなメモリブロックが返されると、最初に解放/削除しない限り、再び返されないことを保証します。つまり、どちらもメモリを「割り当て」ます。

ただし、new/ deleteコンストラクタ、デストラクタ、および演算子のオーバーロードを介して、さらに他の任意の作業を実行します。malloc/freeメモリの割り当てと解放のみを行います。

実際、newは十分にカスタマイズ可能であり、必ずしもヒープからメモリを返したり、メモリを割り当てたりする必要はありません。ただし、デフォルトでnewはそうです。


7

newとmallocの主な違いは、newがオブジェクトのコンストラクターを呼び出し、それに対応するdeleteの呼び出しがオブジェクトのデストラクターを呼び出すことです。

他の違いがあります:

  • newタイプセーフであり、mallocタイプのオブジェクトを返しますvoid*

  • newエラー時に例外をスローし、errnoをmalloc返しNULLて設定します

  • new演算子であり、オーバーロード可能でmallocあり、関数であり、オーバーロードできません

  • new[]配列を割り当てるは、より直感的でタイプセーフです。 malloc

  • malloc由来の割り当てを介してサイズ変更することができreallocnew由来割り当てをリサイズすることができません

  • mallocNバイトのメモリチャンクを割り当てることができますnew。たとえば、char型の配列を割り当てるように要求する必要があります

違いを見ると、要約はmallocがC-esqueで、新しいのはC ++-esqueです。コードベースに適したものを使用してください。

newとmallocを異なるメモリ割り当てアルゴリズムを使用して実装することは正当ですが、ほとんどのシステムでは、newは内部的にmallocを使用して実装されており、システムレベルの違いはありません。


5

これを行わnewないことmallocがいくつかあります。

  1. new そのオブジェクトのコンストラクターを呼び出してオブジェクトを構築します
  2. new 割り当てられたメモリの型キャストを必要としません。
  3. 割り当てられるメモリ量を必要とせず、構築されるオブジェクトの数を必要とします。

したがって、を使用する場合はmalloc、上記のことを明示的に行う必要がありますが、これは必ずしも実用的ではありません。さらに、newオーバーロードすることはできますが、オーバーロードmallocすることはできません。

つまり、C ++を使用する場合はnew、できるだけ使用するようにしてください。


4

また、

グローバルのnewおよびdeleteはオーバーライドできますが、malloc / freeはオーバーライドできません。

さらに多くの新規および削除は、タイプごとにオーバーライドできます。


3

newおよびクラスの新しいインスタンスを宣言または削除するdeleteC ++ プリミティブです(したがって、インスタンスのクラスのデストラクタを呼び出します)。

mallocそしてfreeC 関数ですあり、メモリブロックを割り当てて解放します(サイズ)。

どちらもヒープを使用して割り当てを行います。mallocそしてfree、彼らはただ、おそらくポインタに関連付けされるメモリ空間のチャンクを確保して、それにもかかわらず、より「低レベル」です。そのメモリの周りに構造は作成されません(C配列を構造と見なさない限り)。


1
C ++の新機能は、クラスのインスタンスを宣言しません。(通常)ヒープから1つを割り当て、何も宣言しません。インスタンスを宣言するだけでインスタンスを宣言できます。その場合、宣言の格納期間に応じて、インスタンスはスタックまたはグローバルに配置されます。
スティーブジェソップ

まあ、それはクラスにメモリ空間を割り当てますが、スタックにクラスを格納するという本当の意味ではなく、スタックでクラスを「宣言」することはできません。宣言には、常にスタックに割り当てられるクラスへのポインタのみが含まれ、クラスを保持する実際のメモリはヒープ内にあります。
ホルヘコルドバ、

はい、できます。質問タグによると、これはC ++なので、オブジェクトをスタックに入れることができます。そしてnewは宣言ではなく、式です。何かを宣言して割り当てることは別のことです。
スティーブジェソップ

2

newおよびdeleteはc ++の演算子です。オーバーロードすることもできます。mallocとfreeはcの関数です。

mallocは、newが例外をスローしているときに失敗すると、null ptrを返します。

mallocによって返されたアドレスは、(void *)malloc(size)Newが型付きポインターを返すので、再度型キャストする必要があります。


2
  • newは演算子ですが、malloc()は機能です。
  • newは正確なデータ型を返し、malloc()はvoid *(void型のポインター)を返します。
  • malloc()、メモリは初期化されておらず、デフォルト値はガベージですが、新規の場合、メモリはデフォルト値で初期化されます。
  • deleteとfree()はどちらも「NULL」ポインタに使用できます。

0
  • を使用するにはmalloc()、に必要のないプログラムに <stdlib.h>または を含める<alloc.h>必要がありnewます。
  • newそしてdelete、オーバーロードすることができますが、mallocできません。
  • 配置を使用して、newメモリを割り当てたいアドレスを渡すことができますが、これは可能ではありませんmalloc

1
alloc.hは標準ヘッダーではありません。<new>新しい配置を使用するには、が必要です。
2015

0

削除キーワードまたはフリー関数を使用するためのこのコード。ただし、「malloc」または「new」を使用してポインターオブジェクトを作成し、deleteを使用してオブジェクトメモリの割り当てを解除すると、そのオブジェクトポインターでもクラスの関数を呼び出すことができます。その後、deleteの代わりにfreeを使用すると、freeステートメントの後にも機能しますが、両方を使用すると、クラス内の関数を呼び出すことができないのはポインタオブジェクトだけです。コードは次のとおりです。

#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. new syntexはmalloc()よりも簡単です

2.new/deleteは、malloc()/ free()が関数である演算子です。

3. new / deleteはmalloc()/ free()よりも高速に実行されます。これは、新しいassemlyコードがコンパイラーによって直接貼り付けられるためです。

4.weは、オペレーターのオーバーロードの助けを借りて、プログラムの新規/削除の意味を変更できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.