2016-06-17 11 views
0

私は自分自身にC++を教えています。これは私の最初のプログラミング言語であり、私はポインタのメモリ割り当てに関連する言葉に苦労しています。C++ポインタとメモリの割り当て

は、この文を考えてみましょう:

int *p; 
int x; 
p = &x; 
*p = 8; 

      Value 
&p  1400 
p   1800 
*p  8 
x   8 

&のpは、pのメモリアドレスです。

pは、ポインタpによって指し示されるメモリアドレスです。

* pは、ポインタpが指すメモリアドレスの値です。

私はこれを理解しています。しかし、本の状態:

p = & xはxのアドレスをpに格納します。ただし、新しいメモリは割り当てられません。

これは混乱します。メモリが割り当てられている。そうでなければ、pは未定義である。

は今この文を考えてみます。

int *p; 
p = new int; 
*p = 28; 

をここでは、メモリが割り当てられているので、* pは有効かつ有意義にするために、追加の変数が必要いけません。

彼の文の著者の意味は何である、「メモリが割り当てられていない。」、コードブロックを考えるとき:

だから、私は私の質問がされると思いますか?

+0

おそらくメモリが 'p'と' x'以外に割り当てられていないことを意味します。または、動的メモリ割り当てが行われませんでした。または両方。 – juanchopanza

+0

'p =&x;'ここで 'p'は' x'のメモリ位置を指していますので、すでに割り当てられている*(スタ​​ック上にある)メモリ位置が共有されるため、メモリは割り当てられません。 –

+0

これは単なるセマンティクスです。スタック上のオブジェクトを宣言するCやC++の世界では、(通常は)メモリ割り当てと呼ばれていません。逆に、メモリ割り当ては通常、動的メモリ割り当てを意味します。その特定の本ではなくむしろちょっとした言葉遣いです。 –

答えて

1

p = & xは、xのアドレスをpに格納します。ただし、新しいメモリは割り当てられません。

100%true。すべての割り当ては、前の2行で行われました。

int *p; // allocation of p here 
int x; //allocation of x here 
p = &x; // no allocation here. 
p = &x;

以前に割り当てられたポインタに以前に割り当てられたメモリの場所のちょうど割り当てです。ストレージがスタック、ヒープ、または現在のシステムがスタックまたはヒープの代わりに使用するものに割り当てられるかどうかは関係ありません。

二たとえば、

int *p; //allocation of p here 
p = new int; // allocation of one nameless int AND assignment of that int to p here 
*p = 28; // no allocation 
+0

あなたは絶対に正しいです。これは割り当てステートメントなので、メモリは割り当てられませんでした。うーん..言われている、文ではないだろう:int * p; p =新しいint; 2つのメモリ位置を割り当てる。 1つは最初のステートメントに、もう1つは2番目のステートメントに使用しますか? –

+0

奇妙なことに、私はちょうどそれを扱う編集を終えました。 – user4581301

+0

ハ、大丈夫です。我々は同じページにあったことをうれしい。 –

-1

"p = & xはpのxのアドレスを格納しますが、新しいメモリは割り当てられません。 スタックで 'x'が作成されたため、ヒープ(変数 'p'および他のすべての 'ローカル変数'と同じように)では作成されませんでした。あなたの2番目の例が間違っているようですが、私は100%確実ではありません。

+0

スタック割り当てメモリ割り当てではありませんか? –

+0

技術的には正解ですが、コンパイル時に既知の(おそらく相対的で絶対的ではない)場所で作成/計算されます。 – ABuckau

+0

ですが、割り当て 'p =&x'は* new *メモリ割り当てを行いません。メモリはすでに 'p'の宣言によって割り当てられています。 –

-1

著者はおそらくヒープ割り当てを参照します。 pとxの両方がスタックに割り当てられます。スタックポインタは実際にはマシンのタイプに応じてインクリメント(またはマシンのタイプに応じてデクリメント)されます。彼らは範囲外になると割り当てが解除されます。 OTOHでは、新しいintはヒープメモリから割り当てます。これはおそらく時間がかかりますが、スコープよりも長生きできます。deleteを使用して手作業で割り当てを解除します。いずれの場合でも、ポインタは正常に動作します。これは最初は明白ではないかもしれませんが、スタック上の変数のアドレスか、同じタイプを使用してヒープから割り当てられたアドレスを取ることができます。

0

変数は、最初に変数を宣言するときにスタックに割り当てられます。ここで、メモリは int *p; int x;

に割り当てられます。したがって、p = &x;は、xのメモリアドレスをスタック上のpのために以前に割り当てられたメモリに格納します。一般に「割り当てられた」単一の単語を直接(malloc関数 『またはいくつかの他のそのようなメカニズム『などのキーワード、ライブラリ・ルーチン』新しい「使用ヒープ記憶から割り当て』の略語として使用さ

1

間接的に)。

ここで、 'p =&x;'というステートメントは、 pの値がxの記憶アドレスに設定され、スタックにが割り当てられていることを意味します。スタックストレージはプログラマの裁量ではなく自動的に管理されるため、これを口頭での使用では「割り当て済み」とはしません。

+0

偉大な答え。ありがとうございました。私はあなたの助けに大変感謝しています。 –

0

"p = & xはxのアドレスをpに格納しますが、新しいメモリは割り当てられません。"

これはおそらく、この特定の文でpがxのアドレスをとり、xに新しいメモリが割り当てられていないことを意味すると思います。 xのメモリはおそらく早く割り当てられましたが、pの初期化はxの新しいメモリを割り当てません。

しかし、後者の文で

それは「新しいint」で初期化されるので、割り当てられたメモリの新しいチャンクへ

int *p; 
p = new int; 
*p = 28; 

Pポイント。

-1

は、まあ、私はその本を持って、他の人が提供する説明は正しいですが。ちょうど私のことを追加してください。

関数をコンパイルするときは、可変長の引数でない限り、フレームサイズとフォーマットはコンパイラにすでに知られています。この関数を呼び出すと、コンパイラは呼び出し元関数の上(または下)のスタックにこのフレームのメモリを予約します。これはあなた自身が起こっているのを見ることができます。ほとんどのアーキテクチャで

void fun(){ 
int a,b; 
printf("addr fun &a=%u, &b=%u",&a,&b); 
callfun(); 
} 

void callfun(){ int c; 
printf("addr callfun &c=%u",&c); 
} 

、アドレスが減少見えるかもしれません - しかし、論理的にcalllfun()を呼び出すことによって、我々は前のフレームの上のフレームを作成しました。

したがって、これらの変数のメモリは透過的に作成され、プログラマはそれを気にしていないと言えるでしょう。スタックが大きくなると、より多くのメモリが使用され、関数呼び出しがメインエントリポイント関数に近づくと解放されます。しかし、それ以外の場合、new演算子を使うと、プログラマはスタックに既に割り当てられているものに加えてメモリを明示的に求めます。これは、ヒープと呼ばれるプログラムのアドレス空間内の別の領域から実行されます。 OSはこれを行うための機能を提供します。

あなたのケースでは、これらの変数を持つ関数が既に呼び出されているため、メモリはすでに(スタック上に)割り当てられており、新しいメモリは作成されていないと言っています。ただし、新しい演算子を使用して、必要に応じてさらに多くのメモリを割り当てることができます。

関連する問題