2016-08-15 4 views
2

動的メモリ割り当てに関する質問があります。プログラミング言語間の動的メモリ割り当て

Cになると、メモリが機能をのmalloc()のcalloc()のrealloc()を使用して割り当てられ、フリー()を用いて脱割り当て。

しかしC++C#Javaのなどの反対指向言語では、メモリを動的にC++の場合にキーワード(オペレーター)を削除新しいを使用して割り当てられ、を使用して割り当てを解除されます。

私の質問は、なぜ動的メモリ割り当てのためのこれらのオブジェクト指向言語の関数の代わりに演算子がありますか? newを使用していても、関数のように、割り当て中に最終的にクラスオブジェクト参照にポインタが返されます。

これは構文を簡略化するためだけですか?さらに深刻な理由がありますか?

+0

異なる言語、異なるオペレータ、異なる意味(ここで重要なことである、 'これらの言語でnew'だけのメモリを割り当てるだけではありません)物事が遅くなり、です。 –

+1

私は[なぜJavaがなぜ新しいものを必要とするのか](http://stackoverflow.com/questions/6340535/is-the-new-keyword-in-java-redundant)に疑問を抱いています。通常の非批准的な答えは "because C++"です(面白いのは、C++の 'new'はコードの匂いがしばしばです)。ある時点では、Javaのデザイナーはそれが良いアイデアだと思っていました(私はそれが確信しています)。そしてC#のデザイナーはおそらく "Javaのため"でした。 – juanchopanza

+1

私は根拠があるとは思わない。 StroupstrupはそれがCでどのように行われたかを見て、 "ねえ、これはかなりばかげている"と思った。そして、次に彼は "私は何か眠りにつくことができると確信している!"と思った。バグの潜在能力を最大限に引き出すためのプログラミング言語の設計があります。実際には、new、new []、delete、およびdelete []の4つの演算子があります。あなたが好きなようにそれらを混ぜる。そして、アプリケーション・プログラマーがオーバーロードする可能性があります。 JavaとC#はC++の演算子名をコピー/ペーストするだけです。また、ガベージコレクションがあるので、削除については気にしません。 – Lundin

答えて

4

Cでは、メモリ割り当て関数はそれだけです。彼らはメモリを割り当てます。他に何もない。そして、完了したらそのメモリを解放することを忘れないでください。オブジェクト指向言語(C++、C#、Java(登録商標)、...)で

newオペレータは、メモリを割り当てますが、それはオブジェクトを初期化するための特別な方法であるオブジェクトのコンストラクタを呼び出します。

ご覧のとおり、それは意味的に全く異なることです。 new演算子は単純な構文ではなく、単純なメモリ割り当てとは実際には異なります。

C++では、完了したらそのメモリを解放する必要があります。

C#とJavaでは、ガベージコレクタによって処理されます。

0

オブジェクト指向設計/プログラミングの全体点は、意味のある抽象化を提供することです。

OO設計をうまく行っているときは、メモリ内の領域について(すぐに)考えることはありません。人は物を考えます。状態を運び、行動を提供する。

C++でコードを記述しても、ほとんどの場合、「私のビットが整列する理由」、「実行時に必要なオブジェクトがどれくらいあるか」などの微妙なことを心配する必要はありません。 。もちろん、これらの質問は特定の状況に関係します。しかし、OO設計内。本当の価値は、「あらゆるドメイン」の問題を可能な限り正確、容易、保守可能なものとして解決するのに役立つ有用な抽象概念を作成することから来ています。

"キーワード"と "機能"の関係については、Javaをご覧ください。言語の父親は、単にJavaプログラマが「メモリポインタ」について考え始めるのを望まないだけでした。あなたはオブジェクトだけを扱います。オブジェクトへの参照。したがって、メモリを「割り当てる」という概念と「ポインタ」を返すという概念は、ここにはまったく存在しません。だから、どのようにライブラリメソッドとしてこの機能を提供するだろうか?まあ、あなたがしたいのなら、あなたはできません。

最後に、ある程度まで、これは言語を設計する人々によって「味覚/スタイル」の問題です。時には、人々は小さな言語コアを好むことがあります。ライブラリ内のすべてを行います。他の人は「より多くの」ものを組み込むことを好みます。

+0

はい。しかし、なぜ関数の代わりに演算子ですか? – juanchopanza

+0

"メモリポインタ"は演算子と関数とは関係ありません。 C++では、 'new'式はとにかくポインタを返します。 – juanchopanza

+0

質問者は**メモリ割り当て**について質問しました。彼はこれらの用語を4回使用しました。だから私は思います:それは彼にとって重要です。 – GhostCat

0

私はあなたが言ったように構文を単純化するためだけに行ったと信じています。 演算子は、単にメソッド(または関数)を呼び出す別の方法です。 "12 + 13"を使用することは、Add(12,13)を使用することと変わりありません。これを見るために 方法は、例えば、C#でオペレータのオーバーライドを経由する:

// Sample from - https://msdn.microsoft.com/en-us/library/8edha89s.aspx 
public static Complex operator +(Complex c1, Complex c2) 
{ 
    Return new Complex(c1.real + c2.real, c1.imaginary + c2.imaginary); 
} 

それは通常の方法ですが、複雑なクラス上の演算子の使用を可能にします。 Add演算子を例として使用しています。これは、「new」などのメモリ割り当て演算子と同じであるためです。

+0

Javaでは、 'T t = new T();は' T t();よりも単純な構文です。 – juanchopanza

+1

私は同意しますが、 'T t();'という構文は 'T t = new T();'よりもあまり明確ではないと主張することができます。これは、最初の構文でtに値を視覚的に割り当てないという事実によるものです。二番目には、tが特定の値に等しいことを明確に述べています。 – MichaelThePotato

+0

良い点。したがって、 'T t = T();'となります。 – juanchopanza

0

新しいキーワードは、構文を簡略化するために理想的です。これはかなり示唆的であり、メモリ割り当て以上のものでも、コンストラクタも呼び出します。あなたが言っている

一つのこと:削除し、新規およびキーワード(オペレーター)を使用して

C++、C#とJavaの、メモリを動的に割り当てられ、割り当て解除

JavaとC#のためのそれ新しいキーワードだけです、削除はありません。私はC#であなたがusingブロックを使用して、オブジェクトがもはや使用されていないときにリソースが解放されることを保証できることを知っていますが、Disposeメソッドを呼び出す場合など、

さらに指摘する必要があるのは、オブジェクト指向プログラミング言語の目標は、GhostCatが述べたように、ほとんどの場合メモリがどのように割り当てられているかを考えるようにプログラマーを解放することです。どのようにオブジェクトがリリースされたのか、これがガベージコレクタが導入された理由です。

主な原則は、プログラミング言語が高いほどメモリ管理などのことを抽象化し、実際のビジネス上の問題を解決する簡単な方法を提供することです。もちろん、これは、プログラミング言語が特定のタスクのために選択されたときに考慮されている可能性があります。

+0

Dulyは修正を指摘した。 :) – SoulRayder

+0

@SoulRayderすみません、どの修正? – meJustAndrew

+0

C#とJavaのdeleteキーワードがありません – SoulRayder

0

C:malloccallocは、メモリを割り当てるための基本的な方法はCです。

  • malloc関数は:これは、任意の値に初期化することなく、要求されたサイズに応じて初期化されていないメモリを割り当てる
  • のcalloc:mallocとほぼ同じ、プラスそれはまた、ゼロに初期化(0)。どちらの場合も

、あなたが何かを必要と:

  • 割り当てのために要求されたメモリのサイズは、初期化時に与えられるべきで、それがreallocとともに増加することができます。
  • 割り当てられたメモリ誰かがあなたがメモリ大規模な多くの作業を行っているときfreeは非常に便利ですが、割り当てられたメモリを解放するために良い思い出を持っていない場合、時にはそれがOOMエラーになることができ、freeで削除する必要があります。

NOTEnewdeletenewdelete沿っもmalloccallocあり(無料、あまりにも再割り当て)++ Cを考えることができます:Castingsizeは(メモリを割り当てるため)malloccalloc

C++で必要とされますメモリを割り振りそして解放する現代的な方法としてであるがOOP'sの言語のnot allは両方を持っている。例えばjavadeleteを持たない。

  • newあなたはparameterizedefaultまたはコピーコンストラクタを使用して初期値を設定するためのさまざまなシナリオを持っている場合objectsと協力しながら、それはかなり便利ですので、デフォルト値を初期化するコンストラクタを使用しています。

NOTEnewを使用すると、malloccallocと割り当てのためのメモリサイズを与える必要はありませんとは異なり、適切なケーシングを行う必要はありません。 1つ少ないこと、右。

  • deleteがメモリを解放するために使用される、いくつかのオブジェクト上のdeleteコールはまた、あなたが、現在の状態などを保存するなど、いくつかの別れの作業を行うことができ、そのオブジェクトのライフサイクルの最後の場所であるdestructorを呼び出しますメモリが解放されます。

NoteC#javaでメモリのdeallocationreleaseにメモリ管理がmemory.Itはそのメモリへの参照変数の指示がない場合、メモリを解放するmark-sweepvarious algosを使用したりしGarbage-Collectorによって処理され参照変数の値はnullに設定されます。

もはや必要とされているメモリに、そのオブジェクトを指す参照変数がある場合にもmemory leakにつながる可能性があります。

GCの欠点は、これが

関連する問題