第15講 フリーストア配列
第1話 配列の種類

C言語は長い歴史を持ちます。C言語の中でも何度も改正され、さらにC++へと変貌し拡張してきました。
したがって、配列と同様の働きをもつものも拡張を続けてきて、かなり複雑な様相を呈しています。

ここで配列の種類を、私が理解している範囲で整理してみましょう。
Ⅰ ネイティブ配列
 ⅰ 自動メモリに配置される配列
 ⅱ フリーストアに配置される配列
Ⅱ ポインタ
Ⅲ ベクタ

このうち、Ⅰⅰ自動メモリに配置される配列とⅡポインタとⅢベクタについては既習済みです。
残っているのは、Ⅰのⅱフリーストア配列です。
本講では、フリーストア配列について学んでいきます。

Ⅰⅰ自動メモリに配置される配列とは、
int a[5];
で宣言される配列です。したがって、第6講 配列の学習で学習した配列です。
ネイティブ配列はC言語時からあるもので、C++でももちろん使えるわけです。
C++言語が扱うメモリにはいくつの種類があり、そのうちの2つが自動メモリとフリーストアです。
自動メモリの方は、関数の処理が終わったときなど、変数が使っていたメモリを自動的に開放してくれます。
開放するということは、今まで使っていたメモリ領域を他の変数の領域として割り振ることができるということです。
例えば、ある関数f1()が3つの変数をメモリに割り当てていたとすれば、

a b c

f1()の終了と同時にそのメモリーは解放され、例えば、g1()の変数x、yとh1()の変数pに割り当てることができるということです。

x y p

同じメモリが他の変数の領域として再利用されるのです。
つまり、自動メモリの場合変数の生成と消滅が自動的に行われるわけです。

それに対して、フリーストアの場合は、プログラマが自分で消さないと、メモリ領域は開放されず、
割り当てられているメモリがどんどん増えていってしまいます。

a b c x y p

そうすると使用できるメモリ容量がどんどん減っていってしまいます。
使用できるメモリ容量が減少して行く現象をメモリリークといいます。
リークとは漏れるという意味で、メモリが漏れて減ってしまうことを表しています。
フリーストアの場合、プログラマーが消すのを忘れるとメモリリークを起こすことになります。
では、自動メモリの方が優れているかというとそうではなく、一長一短があります。
プログラマに手を煩わさない自動メモリは容量が小さいのです。
だから、自動メモリに配置されるネイティブ配列の場合、大きな配列を扱うことができません。
それに、対してフリーストアの場合メモリ容量が大きいので、大きな配列を扱うことができます。
さらに、フリーストアの方が優れている点は、実行時に要素数を決められるという利点があります。
この点については、後ほど具体例で説明いたします。

フリーストアに配置されるネイティブ配列を宣言するには、次の構文を使います。
要素の型* 配列名=new 要素の型[要素数]
フリーストア配列を使った最後には、必ずその配列を削除しなければなりません。
メモリリークを起こすからです。
配列を削除するには
delete[] 配列名;
とします。

具体例を挙げましょう。
int* a=new int[5];
(これは
int *a=new int[5];
と書いても同じです。どちらを取るかは個人の好みです。)
これで要素数5の1次元配列が宣言されています。
この配列の使い方は、Ⅰⅰ自動メモリに配置されるネイティブ配列と同じで、
a[0]=5;等と使います。

先に実行時に要素数を決められると説明したのは、次のような例を指しています。
int s=5;
int* a=new int[s];
Ⅰⅰ自動メモリに配置されるネイティブ配列の場合は、
int s=5;
int a[s];
としたのでは、エラーします。
Ⅰⅰ自動メモリに配置されるネイティブ配列はサイズを最初に決めておかないといけないのに対して、
Ⅰⅱ フリーストアに配置される配列の場合は、実行時に要素数を決められるのです。

では実際に、フリーストアに配置される配列(以後フリーストア配列と記述します)をコーティングしてみましょう。
新規にプロジェクトを作成して、コーティングを下のようにしましょう。

#include<iostream>
using namespace std;
void f(int* a);
void g(int* a);
void main(){
   int* a=new int[10];
   int i,j;
   for(i=0;i<10;i++){
     a[i]=i+1;
   }
   for(i=0;i<10;i++){
     cout<<a[i]<<" ";
   }
   cout<<endl;
   cout<<"プロジェクト終了"<<endl;
   delete[] a;
}
フリーストア配列の場合、
必ず関数終了直前にdelete[] a;delete [] a;でも可)を使って削除しなければなりませんので注意しましょう。

実行結果
a

では皆さん問題です。
今回は、mainの中ですべての処理を済ませましたが、
データを作成する部分データを表示させる部分
#include<iostream>
using namespace std;
void f(int* a);
void g(int* a);
void main(){
   int* a=new int[10];
  
f(a);
  
g(a);
   cout<<endl;
   cout<<"プロジェクト終了"<<endl;
   delete[] a;
}
として、同じ実行結果aになるようにコーティングしてください。
f(a)g(a)はvoid型です。




第14講第10話へ
 第2話へ


a

eclipse c++ 入門講義第1部へ

魔方陣 数独で学ぶ V
BA 入門
数独のシンプルな解き方・簡単な解法の研究
VB講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)
初心者のための VC++による C言語 C++ 入門 基礎から応用まで第1部
eclipse java 入門
java 入門 サイト 基礎から応用まで
VC++ C言語 C++ 入門 初心者 基礎から応用まで
本サイトトップへ