CとC++における動的メモリ確保の違い:基礎から理解するメモリ管理
CとC++はいずれも高パフォーマンスな低レベル言語ですが、メモリ管理の方法には明確な違いがあります。この記事では、中級者向けにCとC++における動的メモリ確保の方法とその使い分け、そして内部で起こっている違いを丁寧に解説します。
1. 動的メモリ確保とは?
動的メモリ確保とは、プログラムの実行時にメモリ領域を確保することです。これにより、実行時の状況に応じて柔軟にメモリを使用できるようになります。
主な用途
- ユーザーの入力によってサイズが変わる配列
- リンクリストやツリーなどの動的データ構造
- オブジェクトの動的生成(C++)
2. Cにおける動的メモリ確保
C言語では、標準ライブラリ <stdlib.h>
の関数を使ってメモリを確保します。
主な関数
関数 | 説明 |
---|---|
malloc |
指定バイト数のメモリを確保する |
calloc |
0初期化された複数要素分のメモリを確保 |
realloc |
メモリサイズの再割当 |
free |
確保したメモリを解放 |
使用例
#include <stdio.h> #include <stdlib.h> int main() { int *arr = (int *)malloc(5 * sizeof(int)); if (arr == NULL) { printf("メモリ確保に失敗しました\n"); return 1; } for (int i = 0; i < 5; i++) arr[i] = i * 10; for (int i = 0; i < 5; i++) printf("%d ", arr[i]); free(arr); return 0; }
注意点
malloc
は確保されたメモリを初期化しないfree
を忘れるとメモリリーク- NULLチェックは必須
3. C++における動的メモリ確保
C++では、演算子 new
および delete
を使います。malloc/free
も使用できますが、C++の文法やオブジェクト指向とは相性が悪いため、通常は new/delete
を使います。
基本構文
int* arr = new int[5]; // 配列の確保 delete[] arr; // 配列の解放 int* num = new int; // 単一オブジェクトの確保 delete num; // 単一オブジェクトの解放
使用例
#include <iostream> using namespace std; int main() { int* arr = new int[5]; for (int i = 0; i < 5; i++) arr[i] = i * 10; for (int i = 0; i < 5; i++) cout << arr[i] << " "; delete[] arr; return 0; }
new/deleteの特徴
4. CとC++の違いまとめ
項目 | C | C++ |
---|---|---|
メモリ確保 | malloc , calloc , realloc |
new |
メモリ解放 | free |
delete , delete[] |
型安全性 | 低(キャストが必要) | 高(型を明示して確保) |
コンストラクタ呼び出し | なし | あり |
配列解放方法 | free(ptr) |
delete[] ptr |
例外対応 | なし(失敗時はNULL) | std::bad_alloc をスロー可能 |
5. よくある間違いとトラブルシューティング
malloc
でオブジェクトを作る(C++)
MyClass* obj = (MyClass*)malloc(sizeof(MyClass)); // NG:コンストラクタが呼ばれない
→ 正しくは:
MyClass* obj = new MyClass(); // OK:コンストラクタが呼ばれる
delete
と delete[]
の混同
int* arr = new int[5]; delete arr; // ❌ 未定義動作 delete[] arr; // ✅ 正解
メモリ解放忘れ(リーク)
どちらの言語でも free
や delete
を忘れると、メモリリークになります。ツールを活用して確認しましょう:
- Valgrind(Linux)
- Visual Studioの診断ツール(Windows)
6. C++ではSTLとスマートポインタを使おう
C++では、手動で new/delete
を使うよりも、std::vector
や std::unique_ptr
, std::shared_ptr
を使うのが主流です。
例:std::vector
でメモリ確保
#include <vector> #include <iostream> using namespace std; int main() { vector<int> vec(5); for (int i = 0; i < 5; i++) vec[i] = i * 10; for (int val : vec) cout << val << " "; }
→ delete
の必要がなく、例外安全性も高い!
7. まとめ
CとC++では動的メモリの確保方法や扱い方が大きく異なります。以下のポイントを押さえておきましょう:
- Cでは
malloc/free
、C++ではnew/delete
を使うのが基本 - C++ではコンストラクタ/デストラクタが重要
- C++のスマートポインタやSTLを活用することで、安全で効率的なコードが書ける
delete
とdelete[]
の違いに要注意!
8. 参考リンク
- C言語のmalloc解説(ドットインストール)
- C++におけるnew/deleteの使い方(cppreference)
- Valgrindによるメモリリークチェック
- C++スマートポインタ入門(Qiita)
参考書籍
リンク
リンク
リンク
リンク