私はこれを頭の中で明確にしようとしています。
int* arrayA = new int[3];
int arrayB[3] = {1,2,3}
arrayA = arrayB;
getの値はarrayB
にコピーされarrayA
ますか? またはarrayA
へのポインタになりarrayB
ますか?
私はこれを頭の中で明確にしようとしています。
int* arrayA = new int[3];
int arrayB[3] = {1,2,3}
arrayA = arrayB;
getの値はarrayB
にコピーされarrayA
ますか? またはarrayA
へのポインタになりarrayB
ますか?
特に配列の場合、裸new
は悪です。std::vector
動的配列が必要な場合と静的配列が必要な場合に使用しますstd::array
。1
実際の答えは簡単です。arrayA
ポインタです。を指すように作られていarrayB
ます。これには、次の追加の効果があります。
delete arrayA
と、未割り当てのメモリを解放しようとするため、クラッシュするか、何か不快なことが起こります。実際、C++ では構造体とクラスを割り当てることができますが、配列の割り当てはまったくサポートされていません。オブジェクトの一部が in として管理されているstd::vector
か、in のように配列メンバーとして管理されている場合を除きますstd::array
(注: std::array
C++11 です)。
1主な理由は、コンテナがデストラクタでリソースが解放されることを保証することです。これはRAII イディオムと呼ばれ、メモリ リークやダングリング リファレンスのほとんどの機会を回避します。
int* arrayA = new int[3];
arrayA は、ヒープに格納される 3 つの int を格納するのに十分な大きさの別のメモリ ブロックのメモリにアドレスを格納するようになりました。
int arrayB[3] = {1,2,3};
arrayB は、スタックに格納される 3 つの int を格納するのに十分な大きさのメモリ ブロックです。
arrayA = arrayB;
スタックに格納されているメモリ ブロックのアドレスを変数 arrayA にコピーします。ヒープに格納されているメモリ ブロックへの唯一の参照が失われ、メモリを解放する方法がありません (メモリ リーク)。
スタックに格納され、現在 arrayA によってポイントされているメモリは、現在の関数が戻ったときに安全にアクセスできません。特に、arrayA (または arrayB) を返すことは安全ではありません。
為に
arrayB の値は arrayA にコピーされますか?
いいえ。arrayB を arrayA にコピーしません。そうしたい場合は、次のようにすることができます。
for (int i=0;i<3;i++) arrayA[i]=arrayB[i]; //This is two arrays has same value
arrayA は arrayB へのポインタになりますか?
はい。arrayBの配列へのポインタになります。arrayA = arrayB; の後。ステートメント、最初の行で割り当てられたメモリにアクセスできず、リークです。
配列A=配列B; arrayB のアドレスを arrayA にコピーします。arrayA は arrayB を指し始めます。を使用して確認します。
printf("\n Base address of A[%u] base address of B[%u]", arrayA, arrayB);
お役に立てれば。
Q. Does the value of arrayB get copied over to arrayA?
Ans. NO
または
Q. does arrayA become a pointer to arrayB?
Ans YES.
ただし、new を使用して割り当てたメモリ チャンクは失われます。そのチャンクの開始点であったアドレスを誰も持っていないため。
これは、次のプログラムによって立証されます。
#include<iostream>
using namespace std;
const int MAX=4;
int main(){
int* arrayA = new int[MAX];
for(int i=0;i<MAX;i++){ arrayA[i]=i; }
int arrayB[MAX] = {10,20,30,40};
arrayA = arrayB;
for(int i=0; i<MAX;i++){ cout<<" a["<<i<<"] = "<<arrayA[i]<<endl; }
return 0;
}
このコードの出力は次のとおりです。
a[0] = 10
a[1] = 20
a[2] = 30
a[3] = 40
の上
g++ (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
これは一般的にも当てはまります。
これの視覚化は、このようなものです
arrayA-> [0][1][2][3]
arrayB-> [10][20][30][40]
最初に、arrayA のアドレスは [0] (+ コンパイラが割り当て解除を行うために使用するサイズの負のインデックスの余分なメモリの合計) です。
arrayA=arrayB の後;
arrayA のアドレスは [10] です。
arrayA で delete を呼び出すとしたら、何が起こるでしょうか??
*** Error in `./a.out': double free or corruption (out): 0x00007fff561281d0 ***
これは、次のコードからも明らかです
#include<iostream>
using namespace std;
const int MAX=4;
int main(){
int* arrayA = new int[MAX*2];
for(int i=0;i<MAX;i++){ arrayA[i]=i; }
int* arrayC = new int[MAX];
int j=0;
for(int i=MAX*100;i>=0;i-=10,j++){ arrayC[j]=i; }
arrayA = arrayC;
for(int i=0; i<MAX;i++){ cout<<" a["<<i<<"] = "<<arrayA[i]<<endl; }
delete[] arrayA;
return 0;
}
出力は次のとおりです。
a[0] = 400
a[1] = 390
a[2] = 380
a[3] = 370
*** Error in `./a.out': free(): invalid next size (fast): 0x0000000002028040 ***
Aborted (core dumped)
ただ注意してください:
「無効な次のサイズ」
これは、負のインデックスで arrayA の前に書き込まれたサイズ値について明確に示しています。
配列名は配列のベースアドレスを表します。
配列A=配列B;
arrayB のベースアドレスを arrayA に格納します。ポインター arrayA をインクリメントすることにより、さらなる値にアクセスできます。
すなわち
*(arrayA) 値は 1
*(arrayA+1) 値は 2
*(arrayA+2) 値は 3
作成されたメモリは、最後に解放する必要があります
削除[]配列A