🔰 はじめに
C 言語や C/C++ でよく登場する「ポインタ」「new」「delete」「malloc」「free」…
初心者が必ずつまずく最初の難関です。
メモリって何?どうなってるの?? 必ずと言っていいほどハテナがたくさん 飛び交います。😭
この最初の難関を乗り越えたとしても、 実際にどんなメモリが確保されて、どこが解放されたのか、なんとなくで済ませていませんか?
Ichimi(いちみ)は、CSV に記録したメモリの確保・解放の記録をヒートマップとして可視化するツールです。
この特徴を活かして new / delete の基本動作を “見える化” し、メモリをもっと身近に感じてもらう第一歩にできればと思います。
💡 Ichimi(いちみ)とは?
「Ichimi(いちみ)」は、C/C++プログラムの ヒープメモリ操作を CSV ログからヒートマップ表示するツール です。
- 確保したメモリがどこに割り当てられたか
- 解放した場所がちゃんと戻っているか
- どの時点で断片化やリークしたか
などを、カラフルなヒートマップで直感的に理解できるツールです。
そんな特徴を持つ Ichimi(いちみ)を "メモリの見える学習教材" として役立ててみたいと思います。
💾 Ichimi(いちみ)ダウンロード(BOOTH)
※ この記事のサンプルコードは、 教材同梱 β 版 に含まれます。
🧪 今回試すコード
// テストコード
void test()
{
char* ptr1 = new char[ 100 ]; // 100 バイト確保
char* ptr2 = new char[ 50 ]; // 50 バイト確保
delete[] ptr1; // 解放
delete[] ptr2; // 解放
}
📄 CSV 出力の仕組み
Ichimi は CSV ファイル形式のログを読み込んで表示 します。
CSV は下記のような形式です。
address,size,action,label
CSV のフィールド仕様
フィールド名 | 必須 | 内容 |
---|---|---|
address |
✅ 必須 | メモリアドレスを16進数表記で入力します。0x は省略可能です。例: 10010000
|
size |
⛔ malloc 時のみ必要 | メモリ確保時のサイズを バイト単位 で入力します。free アクションの場合は空でOKです。 |
action |
✅ 必須 | メモリ操作のタイプを指定します。malloc (確保)または free (解放)を記載します。 |
label |
⭕ 任意 | ユニークな識別子として使用可能です。呼び出し元の関数名などを記入すると便利です。 半角65文字 を超えると表示が見切れます。 |
CSV をプログラムから出力する手順
C/C++ プログラムで new / delete を利用してメモリの確保・解放を行い、 実行時に CSV を出力 することで、メモリ時の状態を Ichimi(いちみ)で可視化できます。
#include <stdio.h>
#include <stdlib.h>
// ログファイルポインタ
FILE* logFile = nullptr;
// new[] をフック
void* operator new[]( size_t size )
{
void* ptr = _malloc_base( size );
fprintf( logFile, "%p,%zu,malloc,from new[]\n", ptr, size );
return ptr;
}
// delete[] をフック
void operator delete[]( void* ptr ) noexcept
{
fprintf( logFile, "%p,,free,from delete[]", ptr );
_free_base( ptr );
}
// テストコード
void test()
{
char* ptr1 = new char[ 100 ]; // 100 バイト確保
char* ptr2 = new char[ 50 ]; // 50 バイト確保
delete[] ptr1; // 解放
delete[] ptr2; // 解放
}
// エントリーポイント
int main()
{
// ログファイルを開く
fopen_s( &logFile, "Lesson01.csv", "w" );
if( logFile == nullptr )
{
return 1;
}
// テスト
test();
// ログファイルを閉じる
fclose( logFile );
return 0;
}
すこし複雑になりましたが、 test
関数以外は、 new[] と delete[] をフックして Lesson01.csv
を出力 するコードになります。
今回は new[] / delete[] のみをオーバーロードしていますが、幅広く CSV に出力するには、new / delete、malloc / free、calloc、realloc もオーバーロードしてください。
教材同梱 β 版に同様のコードが含まれますが、構成が異なります。
IchimiLearning01.sln を VisualStudio で開いてご確認ください。
🔍 Ichimi で視覚化!
それでは実行したプログラムで、メモリがどのように確保・解放されるのかを見てみましょう。
-
ブラックサイズを 1B、履歴スライダーを一番左(0)にします。
すると、最初の new[] で確保された 100byte が赤く表示 されます。
💡1B にすると 1 ブロック(1 マス)が 1 バイトとして表示します。
-
さらに履歴スライダーを右に進めていくと、表示が順に変わっていきます。
このような感じで履歴スライダーを最初(左)から最後(右)まで順に進めると、次のように状態遷移が遷移していく様子が確認できます。
細かく見ていくと、次のような感じでメモリの状態が遷移しています。
履歴 | Ichimi の表示 | test 関数の処理 | メモリに発生した事象 |
---|---|---|---|
0 | ![]() |
char* ptr1 = new char[ 100 ] | 100 バイト確保 |
1 | ![]() |
char* ptr2 = new char[ 50 ] | 50 バイト確保 |
2 | ![]() |
delete[] ptr1; | 履歴 0 で確保した 100 バイトを解放 |
3 | ![]() |
delete[] ptr1; | 履歴 1 で確保した 50 バイトを解放 |
🏁 まとめ
如何だったでしょう?
今回は基本的なメモリの確保・解放をしただけの簡単なものですが、 メモリが見える ことで理解が少しは深まったのではないでしょうか。
C/C++ 初心者にとってメモリをイメージして理解することはなかなか難しいものです。
今回の Ichimi(いちみ)の体験を通して、初心者 C/C++ プログラマーのスキルアップ ⤴️ のお役に立てたならウレしいです!😆
📚 さらに学びたい方へ
Ichimi を使った体験記事を予定しています!
- 断片化の視覚化
- メモリリークの視覚化
- 二重解放の動作確認
などなど