どのような場合にmallocやnewを使用しますか?


479

私はC ++でデータを割り当てたり解放したりする方法が複数あることを理解しています。呼び出すmallocときは呼び出す必要がfreeあり、new演算子を使用するときはペアにする必要がdeleteあり、2つを組み合わせるのは誤りです(たとえば、free()作成されたものの呼び出し)newオペレータ)が、私は私が使用する必要があるときにクリアしていないよmalloc/ free私が使用する必要があるときにnew/ delete私の本当の世界のプログラムで。

C ++のエキスパートの場合は、この点に関して従う経験則や慣例を教えてください。


33
2つのスタイルを混在させることはできないことに注意してください。つまり、newを使用してオブジェクトを作成してからfree()を呼び出すことも、malloc()によって割り当てられたブロックを削除することもできません。多分それを言うことは明白ですが、それにもかかわらず...
nsayer

32
良い答えは、私が追加しなければならないすべて(私が見たことがないこと)は、new / deleteがコンストラクタ/デストラクタを呼び出すのに対して、malloc / freeはそうしないことです。言及するだけの違いです。
Bill K

現代のC ++では、どちらを使用するのか理由を見つけようとしています。
Rahly

またはどちらも使用せずにstd:shared_ptr <T>を使用します。その後、まったく削除する必要はありません。
ビンセント、

回答:


387

あなたがCを使用するように強制されていない限り、あなたがすべき使用することはありません malloc。常に使用してくださいnew

大量のデータが必要な場合は、次のようにします。

char *pBuffer = new char[1024];

これは正しくありませんが、注意してください。

//This is incorrect - may delete only one element, may corrupt the heap, or worse...
delete pBuffer;

代わりに、データの配列を削除するときにこれを行う必要があります。

//This deletes all items in the array
delete[] pBuffer;

newキーワードはそれを行うためのC ++の方法であり、それはあなたのタイプがありますことを保証しますコンストラクタが呼ばれますnewキーワードはまた、より多くのあるタイプセーフなのに対し、mallocタイプセーフではありませんすべてで。

データバッファーサイズmalloc変更する必要がある場合は、それを使用することが有益だと私が思う唯一の方法です。newキーワードは次のように類似した方法がありませんrealloc。このrealloc関数は、メモリのチャンクのサイズをより効率的に拡張できる場合があります。

new/ freemalloc/を混在させることはできません。delete

注:この質問の一部の回答は無効です。

int* p_scalar = new int(5);  // Does not create 5 elements, but initializes to 5
int* p_array  = new int[5];  // Creates 5 elements

2
delete [] fooを呼び出す必要があるときにdelete fooを呼び出すことに関して、一部のコンパイラはこれを自動的に修正してリークせず、他のコンパイラは最初のエントリのみを削除してリークします。私はいくつかのコードでこれらのいくつかを持っていました、そしてvalgrindはあなたのためにそれらを見つけます。
KPexEA 2008年

30
正しい削除を使用しない場合、結果は未定義です。不正解です。それが物事の一部になるか、またはうまくいくかもしれないという事実は、時々ただの不運です。
マイケルバー

8
@KPexEA:いくつかのコンパイラがあなたの間違いを修正するかもしれないとしても、そもそもそれらを間違いにするのはまだ間違っています:)常に適切なところでは常にdelete []を使ってください。
korona 2008年

62
「Cの使用を強制されない限り、mallocは決して使用しないでください。常にnewを使用してください。」どうして?ここでの勝利は何ですか?構築が必要なオブジェクトの場合、メモリブロックの場合は、コーディングの誤りを犯す2つの方法を明確に文書化します(新しい場合は()と[]を簡単にキャッチできますが、不一致の配列とスケーラーは新規と削除を簡単にキャッチできます)。rawメモリのブロックにnew / deleteを使用する動機は何ですか?
Ben Supnik、2010

3
@DeadMG:非同期API関数で使用するための配列を作成している場合、new[]より安全ではないでしょうstd::vectorか?を使用する場合new[]、ポインターが明示的に無効になる唯一の方法は、明示的なを介することですdelete。一方、に割り当てられたメモリstd::vectorは、ベクターのサイズが変更されるか、スコープを離れると無効になります。(非同期メソッドがまだ保留中の場合、new[]呼び出しができない可能性を考慮に入れdeleteなければならない場合があることに注意してください。非同期操作を中止する必要がある場合は、コールバックを介して削除を手配する必要があるかもしれません) 。
スーパーキャット2013

144

簡単に言えmallocば、C ++を使用する理由がない限り、C ++には使用しないでください。mallocC ++で使用する場合、多くの欠点があり、new克服するように定義されています。

新しいC ++コードによって修正された欠陥

  1. malloc意味のある方法でタイプセーフではありません。C ++では、からの戻り値をキャストする必要がありますvoid*。これは潜在的に多くの問題を引き起こします:

    #include <stdlib.h>
    
    struct foo {
      double d[5];
    }; 
    
    int main() {
      foo *f1 = malloc(1); // error, no cast
      foo *f2 = static_cast<foo*>(malloc(sizeof(foo)));
      foo *f3 = static_cast<foo*>(malloc(1)); // No error, bad
    }
  2. それよりも悪いです。問題のタイプがPOD(プレーンな古いデータ)である場合、半ば賢明な方法でmallocメモリを割り当てることができます。f2、最初の例のように、。

    タイプがPODかどうかはそれほど明白ではありません。特定の型がPODから非PODに変更され、コンパイラエラーが発生せず、問題のデバッグが非常に困難になる可能性があるという事実は、重要な要素です。たとえば、誰か(おそらく別のプログラマーで、メンテナンス中に、後でfooPODにならなくなった変更を加えた場合)は、コンパイル時に期待どおりの明らかなエラーは表示されません。例:

    struct foo {
      double d[5];
      virtual ~foo() { }
    };

    なるだろうmallocf2いずれかの明確な診断なしに、またなっ悪いです。ここでの例はささいなことですが、誤って非POD性をはるかに遠くに(たとえば、基本クラスで非PODメンバーを追加することによって)導入する可能性があります。C ++ 11 / boostを使用is_podしている場合は、この仮定が正しいことを確認し、正しくない場合にエラーを生成するために使用できます。

    #include <type_traits>
    #include <stdlib.h>
    
    foo *safe_foo_malloc() {
      static_assert(std::is_pod<foo>::value, "foo must be POD");
      return static_cast<foo*>(malloc(sizeof(foo)));
    }

    ただし、boostは C ++ 11やその他のコンパイラー拡張機能がないタイプがPODかどうかを判別できません

  3. mallocNULL割り当てが失敗した場合に返されます。new投げstd::bad_allocます。後でNULLポインタを使用する動作は定義されていません。例外は、スローされたときにクリーンなセマンティクスを持ち、エラーのソースからスローされます。mallocすべての呼び出しで適切なテストでラップするのは、面倒でエラーが発生しやすいようです。(良い作業をすべて元に戻すには、一度忘れるだけです)。例外は、呼び出し側がそれを適切に処理できるレベルに伝播することを許可できますNULLsafe_foo_malloc関数を拡張して、例外をスローするか、プログラムを終了するか、ハンドラーを呼び出すことができます。

    #include <type_traits>
    #include <stdlib.h>
    
    void my_malloc_failed_handler();
    
    foo *safe_foo_malloc() {
      static_assert(std::is_pod<foo>::value, "foo must be POD");
      foo *mem = static_cast<foo*>(malloc(sizeof(foo)));
      if (!mem) {
         my_malloc_failed_handler();
         // or throw ...
      }
      return mem;
    }
  4. 基本的にmallocはC機能でnewあり、C ++機能です。その結果malloc、コンストラクターではうまく機能せず、バイトのチャンクの割り当てのみを確認します。safe_foo_malloc配置を使用するようにさらに拡張できますnew

    #include <stdlib.h>
    #include <new>
    
    void my_malloc_failed_handler();
    
    foo *safe_foo_malloc() {
      void *mem = malloc(sizeof(foo));
      if (!mem) {
         my_malloc_failed_handler();
         // or throw ...
      }
      return new (mem)foo();
    }
  5. 私たちのsafe_foo_malloc関数はあまり一般的ではありません-理想的には、だけでなく、あらゆるタイプを処理できるものが必要ですfoo。これは、デフォルト以外のコンストラクタ用のテンプレートと可変テンプレートを使用して実現できます。

    #include <functional>
    #include <new>
    #include <stdlib.h>
    
    void my_malloc_failed_handler();
    
    template <typename T>
    struct alloc {
      template <typename ...Args>
      static T *safe_malloc(Args&&... args) {
        void *mem = malloc(sizeof(T));
        if (!mem) {
           my_malloc_failed_handler();
           // or throw ...
        }
        return new (mem)T(std::forward(args)...);
      }
    };

    しかし、これまでに確認したすべての問題を修正する際に、デフォルトのnew演算子を実質的に再発明しました。使用mallocして配置newする場合は、new最初から使用することもできます。


27
C ++で作成structしたclassものはあまりにも悪く、基本的に同じことを意味します。structPOD用に予約されていて、おそらくすべてのclassタイプが非PODであると推定されることで問題があったのではないかと思います。C ++の発明以前のコードで定義されたタイプは必ずPODになるため、下位互換性が問題になるとは思わないでしょう。非POD型を宣言するstructよりも利点があるのclassですか?
スーパーキャット2013

1
Aが少し遅れたが、それは結局のところ、作り@supercat structclassほとんど同じことをやっていることは今と呼ばれる巧妙な機能できることが素晴らしいデザインの決断だった(ハーブ)から「メタクラスを」
Rakete1111

@ Rakete1111:一見すると、その提案は、ドルの接頭辞が付いたキーワードを使用する言語のバージョンを前処理しているように見え$classます。しかし、classそれstructが同義語であることと何が関係しているのかはわかりません。
スーパーキャット2018年

@supercat型システムはもっと分岐しているでしょう。事実上同じことclassstruct意味することにより$classclassa を作成することを心配することなく、それらに対して任意の変換を行うことができます()struct
Rakete1111

@ Rakete1111:特定の種類の操作と変換が一部のタイプでは安全で他のタイプでは安全でない場合、タイプにそれを直接識別させ、コンパイラに安全でない操作と変換を拒否させると、 PODSにのみ適した方法は、サイレントに非PODSに変更されます。
スーパーキャット2018年

53

C ++ FQAライト

[16.4]信頼できる古いmalloc()ではなく、なぜ新しいものを使用する必要があるのですか?

FAQ:new / deleteはコンストラクタ/デストラクタを呼び出します。newはタイプセーフですが、mallocはそうではありません。newはクラスによってオーバーライドできます。

FQA:コンストラクター、デストラクター、およびオペレーターのオーバーロードはガベージであり(ガベージコレクションがないとどうなるかを参照)、タイプセーフの問題はここでは非常に小さいため(通常、 mallocによって返されたvoid *を正しいポインタ型にキャストして、それを型付きポインタ変数に代入します。

ああ、そして信頼できる古いmallocを使用すると、同等に信頼できる古いreallocを使用することが可能になります。残念ながら、光沢のある新しいオペレーターの更新などはありません。

それでも、言語がC ++であっても、newは言語全体で使用される一般的なスタイルからの逸脱を正当化するのに十分悪くはありません。特に、単純でないコンストラクタを持つクラスは、単にオブジェクトをmallocすると、致命的な動作をします。それでは、なぜコード全体でnewを使用しないのですか?オペレーターがnewをオーバーロードすることはめったにないので、おそらくあまり邪魔になりません。そして、彼らが新しいものをオーバーロードする場合は、いつでも停止するように依頼できます。

すみません、抵抗できませんでした。:)


7
それは暴動です!ありがとう。
dmckee ---元モデレーターの子猫

8
このコメントは、著者のC ++に対する偏見を明確に示しているため、真剣に受け止めることはできません。C ++は、パフォーマンス指向のソフトウェアを作成するために使用される言語であり、ガベージコレクターはその目的にとって有害で​​ある可能性があります。私はあなたの答え全体に同意しません!
ミゲル

1
@ミゲルあなたは冗談を逃した。
Dan Bechard

50

C ++では常にnewを使用します。型なしメモリのブロックが必要な場合は、演算子newを直接使用できます。

void *p = operator new(size);
   ...
operator delete(p);

3
興味深いことに、このような生データバッファーが必要なときは、常にunsigned charの配列を割り当てました。
グレッグロジャース

セマンティクスが次のようになるように注意してください:p_var = new type(initializer); サイズではありません。
ブライアンR.ボンディ

11
operator newを直接呼び出す場合は、パラメーターとして割り当てるバイト数が必要です。
Ferruccio

1
確かに、この構文について聞いたことがありません。
ブライアンR.ボンディ

9
の反対はoperator newですoperator deletedeletetypeの式を呼び出すのは、明確に定義されたアクションではありませんvoid*
CBベイリー

33

C中心のライブラリとAPIによって管理される予定のメモリを割り当てるためにのみ使用mallocします。使用及び(およびバリアント)あなたがコントロールしていることすべてのため。free newdelete[]


10
また、適切に作成されたCライブラリは内部的にmallocおよびfreeを非表示にすることに注意してください。これがCプログラマーの作業方法です。
Dacav、2013

@dmckee mallocとfreeによってc中心のライブラリを使用するC ++の例はありますか?
マイルマ2013

1
@Dacav:C関数が、関数が戻った後も引き続き使用する必要のあるオブジェクトへのポインターを受け入れ、呼び出し元がオブジェクトがいつ必要かを知る方法がない場合、それは関数にとって完全に合理的です。ポインタがで作成されている必要があることを指定しますmalloc。同様に、のような関数がstrdupオブジェクトを作成して呼び出し元に返す必要がある場合、free不要になったときに呼び出し元がオブジェクトを呼び出さなければならないことを指定することは完全に合理的です。そのような関数は、malloc / freeの使用を呼び出し元に公開することをどのように回避できますか?
スーパーキャット2015

@ supercat、Cはオブジェクトをまったく認識しないため、C関数がオブジェクトへのポインターを受け入れるようにすることには本質的に何か問題があります。一般的に、Cでも割り当て/割り当て解除のセマンティックラッパーを使用するのが最善のアプローチであると私は考えています。Cライブラリが呼び出し元にメモリの事前割り当てまたは割り当て解除、あるいはその両方を要求する場合は、許容範囲内ですが、柔軟性が低くなります。C関数がこれを実行していて、割り当てられたメモリの所有権を主張している場合、mallocを使用してそれを割り当てる必要があります。
Dacav 2015

@supercat誰もが使用していると確信している毎日のパッケージの1つの例はlibgmpです。これまでにオープンソース暗号化またはそのような暗号化に基づくソフトウェアを使用したことがある場合(これは非常に可能性が高い)、おそらく独自の内部データを拡大および縮小する必要のある任意精度の算術ライブラリーを使用したことでしょう。これは初期化関数を使用して行われます...そして、C ++で再コンパイルせずに、C ++でlibgmpであるCコードをどのように使用しますか?今、このことを念頭に置いて(リンカ)と、それについて考える...なぜ任意の賢明な人がなり、これまで置くmallocC ++で?
自閉症の

31

新しいvs malloc()

1)newであり、オペレータが、malloc()ある機能

2)コンストラクターをnew呼び出しますが、呼び出しません。malloc()

3)new正確なデータ型malloc()返しますが、void *を返します

4)NULLをnew返す間は決してNULLを返しません(失敗するとスローしmalloc()ます)

5)newwhile malloc()canで処理されないメモリの再割り当て


6
こんにちは、ポイント4)の場合、失敗時にNULLを返すようにnewに指示できます。 char* ptr = new (std::nothrow) char [323232];
2016年

1
6)mallocはサイズを使用する一方で、コンストラクター引数からの新規作成。
エヴァンモラン

new機能もあります
Ma Ming

Cで再割り当てする傾向がある場合は、reallocではなくを使用mallocして、ポインタ変数をに初期化して開始してくださいNULL。一方、C ++でサイズ変更可能なメモリのチャンクが必要な場合std::vectorは、realloc...またはファイルではなく、
自閉症の

19

あなたの質問に答えるために、あなたは知っておくべきです は、との違いいるmallocありnewます。違いは簡単です:

malloc メモリを割り当てます割り当て、メモリnew 割り当て、コンストラクタを呼び出すいるオブジェクトをます。

したがって、Cに制限されていない限り、特にC ++オブジェクトを扱う場合は、mallocを使用しないでください。それはあなたのプログラムを壊すためのレシピでしょう。

また違いfreedelete全く同じです。違いは、deleteメモリを解放するだけでなく、オブジェクトのデストラクタを呼び出すことです。


13

とには大きな違いが1つmallocありnewます。mallocメモリを割り当てます。Cではメモリの塊がオブジェクトであるため、これはCにとって問題ありません。

C ++では、POD型(C型と同様)を扱っていない場合は、メモリの場所でコンストラクタを呼び出して、実際にオブジェクトをそこに置く必要があります。多くのC ++機能がオブジェクトを自動的に非PODにするため、非PODタイプはC ++で非常に一般的です。

newメモリ割り当て、そのメモリ位置にオブジェクト作成します。非PODタイプの場合、これはコンストラクターの呼び出しを意味します。

このようなことをすると:

non_pod_type* p = (non_pod_type*) malloc(sizeof *p);

取得したポインターはオブジェクトを指していないため、逆参照できません。コンストラクタを使用するには、その前にコンストラクタを呼び出す必要があります(これは、プレースメントを使用して行われますnew)。

一方、次の場合:

non_pod_type* p = new non_pod_type();

常に有効なポインタを取得します。 newオブジェクトを作成したます。

PODタイプでも、2つの間に大きな違いがあります。

pod_type* p = (pod_type*) malloc(sizeof *p);
std::cout << p->foo;

によって作成されたPODオブジェクトmallocは初期化されていないため、このコードは未指定の値を出力します。

ではnew、呼び出すコンストラクタを指定して、明確に定義された値を取得できます。

pod_type* p = new pod_type();
std::cout << p->foo; // prints 0

本当に必要な場合は、useを使用newして、初期化されていないPODオブジェクトを取得できます。詳細については、この別の回答を参照してください。

もう1つの違いは、障害時の動作です。メモリの割り当てに失敗するとmalloc、nullポインタを返しnew、例外をスローします。

前者は使用する前に返されたすべてのポインタをテストする必要がありますが、後者は常に有効なポインタを生成します。

これらの理由により、C ++コードではnew、ではなくを使用する必要がありますmalloc。しかし、それでも、new後で解放する必要があるリソースを取得するため、「オープン」で使用しないでください。使用するnewときは、その結果をすぐにリソース管理クラスに渡す必要があります。

std::unique_ptr<T> p = std::unique_ptr<T>(new T()); // this won't leak

7

動的割り当てが必要になるのは、オブジェクトのライフタイムが作成されたスコープとは異なる必要がある場合(これは、スコープを小さくする場合にも適用されます)に値で格納しないという特定の理由がある場合です作業。

例えば:

 std::vector<int> *createVector(); // Bad
 std::vector<int> createVector();  // Good

 auto v = new std::vector<int>(); // Bad
 auto result = calculate(/*optional output = */ v);
 auto v = std::vector<int>(); // Good
 auto result = calculate(/*optional output = */ &v);

C ++ 11以降、std::unique_ptr割り当てられたメモリの所有権を含む割り当てられたメモリを処理する必要があります。std::shared_ptr所有権を共有する必要がある場合のために作成されました。(これは、優れたプログラムで期待するよりも少なくて済みます)

インスタンスの作成は非常に簡単になります。

auto instance = std::make_unique<Class>(/*args*/); // C++14
auto instance = std::make_unique<Class>(new Class(/*args*/)); // C++11
auto instance = std::make_unique<Class[]>(42); // C++14
auto instance = std::make_unique<Class[]>(new Class[](42)); // C++11

C ++ 17 std::optionalは、メモリ割り当てを必要としないようにすることもできます。

auto optInstance = std::optional<Class>{};
if (condition)
    optInstance = Class{};

「インスタンス」が範囲外になるとすぐに、メモリはクリーンアップされます。所有権の譲渡も簡単です。

 auto vector = std::vector<std::unique_ptr<Interface>>{};
 auto instance = std::make_unique<Class>();
 vector.push_back(std::move(instance)); // std::move -> transfer (most of the time)

それで、いつあなたはまだ必要newですか?C ++ 11以降ではほとんどありません。std::make_unique生のポインタを介して所有権を転送するAPIに到達するまでに使用するもののほとんど。

 auto instance = std::make_unique<Class>();
 legacyFunction(instance.release()); // Ownership being transferred

 auto instance = std::unique_ptr<Class>{legacyFunction()}; // Ownership being captured in unique_ptr

C ++ 98/03では、手動でメモリ管理を行う必要があります。この場合は、より新しいバージョンの標準にアップグレードしてください。行き詰まっている場合:

 auto instance = new Class(); // Allocate memory
 delete instance;             // Deallocate
 auto instances = new Class[42](); // Allocate memory
 delete[] instances;               // Deallocate

メモリリークが発生しないように、所有権を正しく追跡していることを確認してください。移動セマンティクスもまだ機能しません。

では、C ++でmallocが必要になるのはいつですか?唯一の有効な理由は、メモリを割り当て、後でnewを配置して初期化することです。

 auto instanceBlob = std::malloc(sizeof(Class)); // Allocate memory
 auto instance = new(instanceBlob)Class{}; // Initialize via constructor
 instance.~Class(); // Destroy via destructor
 std::free(instanceBlob); // Deallocate the memory

上記は有効ですが、これはnew-operatorを介して行うこともできます。std::vectorこれは良い例です。

最後に、部屋にはまだ象がいますC。メモリがC ++コードで割り当てられ、Cコードで解放される(またはその逆)Cライブラリを使用する必要がある場合は、malloc / freeを使用する必要があります。

この場合は、仮想関数、メンバー関数、クラスを忘れてください... PODを含む構造体のみが許可されます。

ルールのいくつかの例外:

  • mallocが適切な場合に、高度なデータ構造を持つ標準ライブラリを作成している
  • 大量のメモリを割り当てる必要があります(10GBファイルのメモリコピーでは?)
  • 特定の構成要素を使用できないツールがあります
  • 不完全なタイプを保存する必要があります

6

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

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

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


5

構築/破壊を必要とせず、再割り当てが必要なデータ(たとえば、intの大きな配列)を扱う場合、malloc / freeは、reallocを提供するので、良い選択だと思います。これは、new-memcpyよりもはるかに高速です。 -delete(これは私のLinuxボックスにありますが、これはプラットフォームに依存している可能性があります)。PODではなく、構築/破棄が必要なC ++オブジェクトを使用する場合は、newおよびdelete演算子を使用する必要があります。

とにかく、スピードブーストを利用できる場合(mallocされたメモリを解放し、newで割り当てられたオブジェクトを削除する場合)、両方を使用すべきでない理由はわかりません(大きな配列を再割り当てする場合、重要な場合があります) PODの)reallocはあなたに与えることができます。

ただし、必要でない限り、C ++ではnew / deleteを使用する必要があります。


3

C ++に移植したいCコードがある場合は、malloc()呼び出しをそのままにしておくことができます。新しいC ++コードの場合は、代わりにnewを使用することをお勧めします。


3

C ++を使用している場合は、演算子であるため、malloc / callocの代わりにnew / deleteを使用してみてください。malloc / callocの場合、別のヘッダーを含める必要があります。同じコードで2つの異なる言語を混在させないでください。彼らの仕事はあらゆる点で似ており、どちらもハッシュテーブルのヒープセグメントから動的にメモリを割り当てます。


2

new 構造体のデフォルト値を初期化し、その中の参照をそれ自体に正しくリンクします。

例えば

struct test_s {
    int some_strange_name = 1;
    int &easy = some_strange_name;
}

そのnew struct test_sため、mallocされたバージョンにはデフォルト値がなく、インターン参照は初期化されませんが、作業参照を含む初期化された構造を返します。


1

低い視点から見ると、newはメモリを与える前にすべてのメモリを初期化しますが、mallocはメモリの元の内容を保持します。


4
newは通常、メモリを初期化しませんが、それを実現する方法はいくつかあります。それについての1つの議論については、stackoverflow.com / questions / 2204176 /…を参照してください。
wjl

0

次のシナリオでは、コンストラクタを呼び出すため、newを使用できません。

class  B  {
private:
    B *ptr;
    int x;
public:
    B(int n)  {
        cout<<"B: ctr"<<endl;
        //ptr = new B;  //keep calling ctr, result is segmentation fault
        ptr = (B *)malloc(sizeof(B));
        x = n;
        ptr->x = n + 10;
    }
    ~B()  {
        //delete ptr;
        free(ptr);
        cout<<"B: dtr"<<endl;
    }
};

0

newそしてdelete、オペレータは、クラスや構造、一方を操作することができますmallocし、free必要がキャストされることメモリのブロックでのみ動作します。

new/delete割り当てられたメモリを必要なデータ構造にキャストする必要がないため、を使用するとコードの改善に役立ちます。


0

new / deleteの代わりにmalloc / freeを使用することを検討するまれなケースは、C ++でreallocするのと同様の関数がないためです(ただし、これは、より多くのC ++アプローチ)。


-4

malloc()はCでメモリを動的に割り当てるために使用されますが、c ++ではnew()によって同じ処理が行われます。したがって、2つの言語のコーディング規約を混在させることはできません。callocとmalloc()の違いを尋ねるといいでしょう


2
あなたは、することができます(ただし、ほとんど常にべきではありません)を使用するmallocC ++で。
interjay 2012

1
また、スマートポインターを使用しない限り、動的メモリ割り当てを回避することを目指すべき主要なポイントを逃しました。あなたは他の賢明な痛みのために自分を準備しているだけです
thecoshman
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.