C言語の動的メモリ割り当てを具体例でわかりやすく解説
問題
ユーザーが入力したn個の数値について、C言語の動的メモリ割り当て(ダイナミックメモリアロケーション)を使ってメモリ領域を確保し、その合計値を求めるプログラムを作成します。
解決策
動的メモリ割り当てを利用すると、Cプログラマは実行時(ランタイム)に必要な分だけメモリを確保できます。これにより、あらかじめ固定サイズの配列を宣言する場合と異なり、メモリの無駄を大幅に削減できるのが大きなメリットです。
C言語で実行時に動的にメモリを確保するために使用される主な関数は以下の通りです。
- malloc() − 実行時に指定したバイト数のメモリブロックを1つ確保します。
- calloc() − 実行時に連続した複数のメモリブロックを確保し、0で初期化します。
- realloc() − すでに確保済みのメモリ領域を縮小または拡張するために使用します。
- free() − 以前に確保したメモリ領域を解放(デアロケート)します。
以下のCプログラムは、n個の数値を入力して各要素を表示し、その合計を計算するものです。
動的メモリ割り当て関数を使用することで、必要なサイズのメモリだけを確保し、メモリの無駄遣いを防ぐことができます。また、malloc()の戻り値がNULLかどうかを必ずチェックし、メモリ確保が成功したかどうかを確認することも重要なポイントです。
サンプルコード
#include<stdio.h>
#include<stdlib.h>
void main(){
//変数・ポインタ・合計値の宣言//
int numofe,i,sum=0;
int *p;
//ユーザーから要素数を読み込む//
printf("Enter the number of elements : ");
scanf("%d",&numofe);
//malloc()関数の呼び出し//
p=(int *)malloc(numofe*sizeof(int));
/*結果の出力 -
メモリが正常に確保できたかどうかを
確認するためif文を使用する*/
if (p==NULL){
printf("Memory not available");
exit(0);
}
//要素の入力//
printf("Enter the elements : \n");
for(i=0;i<numofe;i++){
scanf("%d",p+i);
sum=sum+*(p+i);
}
printf("\nThe sum of elements is %d",sum);
free(p);//確保したメモリを解放//
printf("\nDisplaying the cleared out memory location : \n");
for(i=0;i<numofe;i++){
printf("%d\n",p[i]);//ゴミ値(不定な値)が表示される//
}
}
実行結果
Enter the number of elements : 5 Enter the elements : 23 34 12 34 56 The sum of elements is 159 Displaying the cleared out memory location : 12522624 0 12517712 0 56
解説のポイント
このプログラムでは、まず要素数をユーザーから受け取り、malloc()によってその要素数に応じたint型分のメモリを実行時に確保しています。入力された各要素の合計を計算して表示した後、free()でメモリを解放しています。
解放後のメモリ領域にアクセスすると、実行結果のように意味のない値(ゴミ値)が表示されます。これはメモリがすでに解放され、内容が保証されていないことを示しており、free()後のポインタへアクセスしないことが重要である理由を理解する良い例といえます。
-
TCMallocを使ってRubyのメモリ割り当てをプロファイリングする方法
Rubyでは、メモリの割り当てはどのように行われているのでしょうか? Rubyは「ページ(page)」と呼ばれる塊単位でメモリを確保し、新しく生成されたオブジェクトはこのページの中に格納されていきます。 しかし、 ページがいっぱいになると、さらなるメモリが必要になります。 そのときRubyは、malloc関数を使ってオペレーティングシステム(OS)に追加のメモリを要求します。 このmalloc関数はOS標準で提供されているものですが、代替となる実装に差し替えることも可能です。 その代表的な実装のひとつが、Google製のTCMallocです。 TCMallocは「gperftools(Goog
-
Redis GEORADIUSBYMEMBERコマンドの使い方を実例付きで解説 – Redisチュートリアル
このチュートリアルでは、Redisに保存された地理空間データ(ジオスペーシャル値)の中から、特定の範囲内に含まれる要素を取得する方法を学びます。そのために使用するのが GEORADIUSBYMEMBER コマンドです。 GEORADIUSBYMEMBERコマンドとは GEORADIUSBYMEMBERコマンドは、キーに保存された地理空間値(ソート済みセット)のメンバーのうち、指定したメンバーの経度・緯度と半径の引数から算出される円形エリアの境界内にある1つ以上のメンバーを返すために使用します。このエリアは、指定したメンバーの経度・緯度を円の中心位置とし、指定した単位による半径を円の半径として計