web-dev-qa-db-ja.com

c ++「ポインタ=新しいタイプ[]」ではなく「ポインタ=新しいタイプ」とは何ですか?

多くのチュートリアルでは、動的メモリに関する最初のコードサンプルは次の行から始まります。

int * pointer;
pointer = new int;        // version 1
//OR
pointer = new int [20];    // version 2

彼らは常に2番目のバージョンがどのように機能するかを説明しますが、最初のバージョンについて話すことは完全に避けます。

私が知りたいのは、pointer = new int作成しますか?私はそれで何ができますか?どういう意味ですか?すべてのチュートリアルは、必ず最初のバージョンについて完全に話すことを避けます。私が(いじりながら)見つけたのはこれだけです:

#include <iostream>

using namespace std;

int main()
{
    int * pointer;
    pointer = new int;
   pointer[2] = 1932;   // pointer [2] exists? and i can  assign to it?!
   cout << pointer[2] << endl;      // ... and access it successfully?!
};

pointerに添え字を付けることができるという事実は、これまでのところpointer = new int暗黙的に配列を作成します。もしそうなら、それはどのくらいのサイズですか?

誰かが私のためにこれをすべてクリアするのを手伝ってくれるなら、私は感謝するでしょう...

16
code shogan

これは、初心者向けのCおよびC++の一般的なエラーです。最初の文は、intだけを保持するためのスペースを作成します。 2つ目は、それらのintsを20個保持するためのスペースを作成します。ただし、どちらの場合も、動的に予約された領域の先頭のアドレスをpointer変数に割り当てます。

混乱を助長するために、ポインタが指しているメモリが無効な場合でも、(pointer[2]を入力すると)インデックス付きのポインタにアクセスできます。の場合:

int* pointer = new int;

pointer[2]にアクセスできますが、動作は定義されていません。 yoは、これらのアクセスが実際に発生しないことを確認する必要があり、コンパイラは通常、このタイプのエラーを防ぐためにほとんど何もできないことに注意してください。

13
Diego Sevilla

先生はこう説明しました。
映画について考えてみてください。実際の座席はメモリ割り当てであり、取得するチケットはポインタです。

int * pointer = new int;

これは1席の映画館で、ポインターはその席へのチケットになります

pointer = new int [20] 

これは20席の映画館で、ポインターは最初の席へのチケットになります。ポインタ[1]は2番目の座席へのチケットであり、ポインタ[19]は最後の座席へのチケットです。

あなたがするときint* pointer = new int;そしてアクセスpointer[2]誰かを通路に座らせている、つまり未定義の振る舞い

12
Default

これにより、整数が1つだけ作成されます。

pointer = new int;        // version 1

これにより、20個の整数が作成されます。

pointer = new int [20]    // version 2

ポインタ[2]は*(ポインタ+ 2)として変換されるため、以下は無効です。作成/割り当てられていません。

int main()
{
    int * pointer;
    pointer = new int;
   pointer[2] = 1932;   // pointer [2] exists? and i can  assign to it?!
   cout << pointer[2] << endl;      // ... and access it succesfuly?!
};

乾杯!

9
Ricko M

new int[20]は、サイズ20の整数配列にメモリを割り当てます、およびそれへのポインタを返します。

new intは単にone整数にメモリを割り当て、それへのポインタを返します。暗黙的に、それはnew int[1]と同じです。

両方のポインタで逆参照(つまり、*pを使用)できますが、p[i]によって返されるポインタでのみnew int[20]を使用する必要があります。

p[0]は引き続き両方で機能しますが、誤って混乱して間違ったインデックスを設定する可能性があります。

Update:もう1つの違いは、配列にはdelete[]を使用し、整数にはdeleteを使用する必要があることです。

2
evgeny

pointer = new intは、1つのintを格納するのに十分なメモリをヒープに割り当てます。

pointer = new int [20] 20 intsを格納するためにメモリを割り当てます。

どちらの呼び出しも、新しく割り当てられたメモリへのポインタを返します。

注:初期化される割り当てられたメモリに依存しないでください。ランダムな値が含まれている可能性があります。

1
Tony the Pony

pointer = new int;は整数を割り当て、そのアドレスをpointerに格納します。 pointer[2]pointer + 2の同義語です。それを理解するには、ポインタ演算について読んでください。この行は、以前に割り当てなかったメモリにアクセスしているため、実際には未定義の動作であり、運が良ければ機能します。

1
Björn Pollex

* "ポインタに添え字を付けることができるという事実は、これまでのところ私がpointer = new int暗黙的に配列を作成します。もしそうなら、それはどのくらいのサイズですか? "*

これは私が最も好きであなたが強調した質問の一部でした。

ご存知のとおり、動的メモリ割り当ては、指定されたプログラムに固有のスタック上のスペースを利用します。新しい演算子の定義を詳しく見てみると:-

void* operator new[] (std::size_t size) throw (std::bad_alloc);

これは実際にはその特定のサイズのオブジェクトの配列を表し、これが成功すると、自動的に構築配列内の各オブジェクトを表します。したがって、オブジェクトはすでに初期化/構築されているため、サイズの範囲内で自由に使用できます。

int * pointer = new int;

一方、上記の例では、次のいずれかの場合に未定義の動作が発生する可能性があります。

*(pointer + k) or *(k + pointer)

使用されています。ポインタを使用して特定のメモリ位置にアクセスできますが、その特定のオブジェクトが作成または構築されていないため、保証はありません。これは、特定のプログラムのスタックに割り当てられていないスペースと考えることができます。

お役に立てれば。

1
NirmalGeo

int* p = new intはメモリをone整数に割り当てます。暗黙的に配列を作成することはありません。 p[2]を使用してポインタにアクセスする方法では、無効なメモリ位置に書き込んでいるときに未定義の動作が発生します。配列は、new[]構文を使用する場合にのみ作成できます。このような場合、delete[]を使用してメモリを解放する必要があります。 newを使用してメモリを割り当てた場合、それは単一のオブジェクトを作成していることを意味し、deleteを使用してメモリを解放する必要があります。

0
Naveen

配列は作成されません。単一の整数を作成し、その整数へのポインタを返します。ポインタ[2]を書き込むときは、割り当てていないメモリを参照します。あなたは注意する必要があり、これをしないでください。そのメモリは、私が信じているあなたが望まない外部プログラムから編集することができます。

0
Narek
int * pointer; pointer = new int;  // version 1
//OR 
pointer = new int [20]             // version 2 

私が知りたいのは、pointer = new int作成しますか?私はそれで何ができますか?どういう意味ですか?すべてのチュートリアルは必ず最初のバージョンについて話すことを避けます

チュートリアルがそれをどうするかを教えてくれない理由は、それが本当にisまったく役に立たないからです!単一のintを割り当て、それへのポインタを提供します。

問題は、intが必要な場合は、宣言するだけではどうでしょうか。

int i;
0
Bo Persson