C++動的割当て


1.インスタンステンプレートの動的割当て:
void alloc(int n){
	//  1,  (      )
	int *value = new int[n];//    
	int *a = new int(4);//    
	
	//  2,   (           )
	for(int i=0; i<n; i++) value[i]=0;
	
	//  3,  
	delete[] value;//    
	delete a;//         
	
	//  4,   
	value = NULL;
	a = NULL;
}

2.動的割当転載
from: http://hi.baidu.com/xiaomeng008/blog/item/9b7706b0e39d785e08230226.html
ダイナミックメモリ割り当て
1.ヒープメモリの割り当て:
C/C++は4つのメモリ区間を定義した:コード領域、グローバル変数と静的変数領域、局所変数領域すなわちスタック領域、動的記憶領域、すなわちスタック(heap)領域またはフリー記憶領域(free store).
スタックの概念:
通常は変数(またはオブジェクト)を定義し、コンパイラはコンパイル時にその変数(またはオブジェクト)のタイプに基づいて必要なメモリ領域の大きさを知ることができ、システムは適切な時に決定されたメモリ領域を割り当てることができる.このメモリ割り当てを静的ストレージ割り当てと呼ぶ.
一部のオペレーティングオブジェクトは、プログラムの実行時にのみ決定され、コンパイル時に記憶領域を予約できないため、プログラムの実行時にのみ、システムが実行時の要求に応じてメモリ割り当てを行う方法を動的記憶割り当てと呼びます.すべてのダイナミックストレージ割り当ては、スタック領域で行われます.
プログラムが動的に割り当てられた変数またはオブジェクトを必要とするまで実行される場合、その変数またはオブジェクトを格納するために、スタック内の必要なサイズの格納空間をシステムに申請する必要があります.変数またはオブジェクトが使用されなくなった場合、つまりそのライフが終了した場合、使用されたストレージスペースを明示的に解放することで、システムはスタックスペースを再割り当てし、限られたリソースを繰り返し使用することができます.
2.スタックメモリの割り当てと解放
スタックスペースの申請、解放方法:
C++では、newとdeleteの2つの演算子を使用して、スタックに割り当てられた格納スペースを申請および解放します.
ポインタ変数名=newタイプ名(初期化式);
deleteポインタ名;
例:
1、 int *pi=new int(0);
次のコード・シーケンスとほぼ同等です.
2、int ival=0, *pi=&ival;
違い:piが指す変数はライブラリオペレータnew()によって割り当てられ、プログラムのスタック領域にあり、オブジェクトは名前が付いていません.  
ヒープスペースの申請、リリースの説明:
⑴.new演算子は、割り当てられたタイプの変数(オブジェクト)を指すポインタを返します.作成された変数またはオブジェクトは、そのポインタによって間接的に操作され、動的に作成されたオブジェクト自体に名前がありません.
⑵.一般的に変数とオブジェクトを定義するときは、識別子で名前を付け、名前を付け、動的に名前を付けます(スタック領域の一時オブジェクトとの違いに注意してください.ライフサイクルが異なり、操作方法が異なり、一時変数はプログラマーに対して透明です).
⑶.スタック領域は、割り当て時に自動的に初期化されない(クリアを含む)ので、初期化式(initializer)で明示的に初期化する必要があります.New式の動作シーケンスは、スタック領域からオブジェクトを割り当て、カッコ内の値でオブジェクトを初期化します.
3.スタックスペース申請、デモンストレーションの解放:
⑴.初期化式(initializer)で明示的に初期化する
int *pi=new int(0);
⑵.piライフサイクルが終了すると、piが指すターゲットを解放する必要があります.
delete pi;
注意このとき、piが指すターゲットのメモリ領域、すなわち、動的メモリ解放(dynamicmemory deallocation)と呼ばれるターゲットが取り消されたが、ポインタpi自体は取り消されず、それ自体は依然として存在し、このポインタが占めるメモリ領域は解放されていない.
次にnew操作について説明します
⑴.new演算子は、割り当てられたタイプの変数(オブジェクト)を指すポインタを返します.作成された変数またはオブジェクトは、そのポインタによって間接的に操作されますが、動的に作成されたオブジェクト自体には名前がありません.
⑵.一般的に変数とオブジェクトを定義するときは、識別子で名前を付け、名前を付け、動的に名前を付けます(スタック領域の一時オブジェクトとの違いに注意してください.ライフサイクルが異なり、操作方法が異なり、一時変数はプログラマーに対して透明です). 
⑶.スタック領域は、割り当て時に自動的に初期化されない(クリアを含む)ので、初期化式(initializer)で明示的に初期化する必要があります.New式の動作シーケンスは、スタック領域からオブジェクトを割り当て、カッコ内の値でオブジェクトを初期化します.
4.スタックに動的な1次元配列を作成する
①配列スペースの申請:
ポインタ変数名=newタイプ名[下付き式];
注:下付き文字列式は定数式ではありません.つまり、コンパイル時に値を決定する必要はありません.実行時に決定できます.
②配列スペースを解放する:
delete[]配列を指すポインタ変数名;
注:四角カッコは非常に重要です.delete文に四角カッコが少なくなった場合、コンパイラはポインタが配列の最初の要素を指していると考えています.回収が徹底していないという問題(最初の要素が占める空間のみを回収)が発生し、角カッコを付けると配列を指すポインタに変換され、配列全体を回収します.delete[]の角カッコには配列要素数を記入する必要はなく、システムは自覚しています.書いてもコンパイラは無視します.
#include
#include
void main(){
     int n;
     char *pc;
cout<<「動的配列の要素個数を入力してください」<     cin>>n;//n運転時決定、17入力可能
     pc=new char[n];//申請17文字(漢字8文字と終了文字1文字)のメモリスペース
strcpy(pc、「スタックメモリの動的割り当て」);//
     cout<     delete []pc;//PCが指すn文字のメモリ領域を解放
     return ;
}
5.動的1次元配列の説明
①変数nはコンパイル時に確定した値ではなく、実行中に入力し、実行時に必要なスタック空間を割り当てる点が動的割り当ての利点であり、配列の「大開小用」の弊害を克服することができ、表、並べ替えと検索におけるアルゴリズムは、動的配列を用いると汎用性がより良い.注意:delete[]pcはn文字の空間を解放し、delete pcでは1文字の空間しか解放しない.
2 char*pc 1がある場合、pc 1=pとなり、delete[]pc 1を使用して空間を解放することができます.C++は配列を境界チェックしないが,スタック空間割り当てでは配列割り当て空間の大きさが記録される.
③初期化式(initializer)がなく、配列を初期化することはできません.
6.ポインタ配列と配列ポインタ
ポインタのタイプ:
(1)int*ptr;//ポインタが指すタイプはint
(2)char*ptr;//ポインタが指すタイプはcharです
(3)int**ptr;//ポインタが指すタイプはint*(つまりint*型ポインタ)
(4)int(*ptr)[3];//ポインタが指すタイプはint([3]//2次元ポインタの宣言
ポインタ配列:(重心はポインタで、ポインタを格納する配列)
1つの配列に格納されているのは同じタイプのポインタで、通常はポインタ配列と呼ばれています. 
例えばint*a[2];int*型変数が2つ入っています
int * a[2]; 
a[0]= new int[3]; 
a[1]=new int[3]; 
delete a[0]; 
delete a[1]; 
ここでは配列でありdelete[]はできません. 
配列ポインタ:(重心は配列で、ポインタで配列を表す)
1次元または多次元配列を指すポインタ.(配列で示すポインタ)
int * b=new int[10];1次元配列を指すポインタb; 
注意、このときスペースを解放するにはdelete[]が必要です.そうしないとメモリが漏れ、bは空のサスペンションポインタになります.
int (*b2)[10]=new int[10][10]; なお、ここでのb 2は、2次元int型配列のヘッダアドレスを指す. 
注:ここで、b 2は2 D配列名に等しいが、その境界、すなわち最上位次元の要素数は示されていないが、その最低次元数の要素数は指定しなければならない.文字を指すポインタ、すなわち等価な文字列のように、文字を指すポインタを文字列を指すポインタとは言わないでください.
int(*b3) [30] [20];//3 Dポインタ――>3 D配列を指すポインタ; 
int(*b2) [20];//二次ポインタ;——>2 D配列へのポインタ 
b3=new int [1] [20] [30]; 
b2=new int [30] [20]; 
この2つの動的配列を削除するには、次の式を使用します.
delete [] b3;//3 D配列を削除(解放)する.
delete [] b2;//2 D配列を削除(解放)する.
スタック内の動的多次元配列の作成
新タイプ名[下付き表現1][下付き表現2]......;
たとえば、動的3 D配列を作成します.
float (*cp)[30][20] ;//30行20列の配列を指すポインタ、2 D配列を指すポインタ
cp=new float [15] [30] [20];//15個の30*20配列からなる配列を確立する.
注意:cpは3 D配列名に等しいが、その境界、すなわち最高次元の要素数は示されていない.文字を指すポインタが文字列に等しいように、文字を指すポインタを文字列を指すポインタとは言わないでください.これは配列のネスト定義と一致します.