プログラム 技術

C言語、C++、C#のメモリの挙動について

ふとメモリの挙動についてそういえばどうだったかなと思い、C言語、C++、C#のメモリの挙動について調べたのでまとめてみました

C言語の場合

自前でメモリの取得および開放をしないとその処理中残り続ける

メモリの確保

  • malloc : 指定されたサイズのメモリブロックを確保し、その先頭アドレスを返す
  • calloc : 指定された数の要素それぞれに対して指定されたサイズのメモリブロックを確保し、その先頭アドレスを返す。確保されたメモリはゼロクリアする
  • realloc : 既に確保されたメモリブロックのサイズを変更する。新しいサイズが元のサイズより小さい場合、データの一部が失われる可能性がある
// mallocの使い方
int* ptr = (int*)malloc(10 * sizeof(int)); // int型の配列を10個分確保

// callocの使い方
int* ptr1 = (int*)calloc(10, sizeof(int)); // int型の配列を10個分確保し、ゼロクリア

// reallocの使い方
// メモリブロックのサイズを20個分に変更
int* new_ptr = (int*)realloc(ptr, 20 * sizeof(int));
if (new_ptr == NULL) {
    // メモリ再確保に失敗した場合の処理
}

ptr = new_ptr;

reallocの注意点

上記のコードでもメモリを改めて取得する際に別変数として取得してから元の変数に代入していますが、元の変数で処理してしまうとめんどうなことになるためです。詳しくは以下のサイトを参照してください

参考サイト
C,C++におけるメモリの扱い方について(初心編) #メモリ管理 - Qiita
C,C++におけるメモリの扱い方について(初心編) #メモリ管理 - Qiita

昨今はJavaやC#などメモリの扱いを気にしなくて良い環境が増えておりメモリ管理の存在そのものを知らない人も少なくない今 ...

続きを読む

メモリの解放

  • free : malloc、calloc、reallocなどの関数で確保されたメモリを解放する
// freeの使い方(使い方は全部一緒)
int* ptr = (int*)malloc(10 * sizeof(int)); // int型の配列を10個分確保
if (ptr == NULL) {
    // メモリ確保に失敗した場合の処理
    return 1;
}
// メモリを使用する処理
free(ptr); // メモリを解放

C++の場合

この言語も自前でメモリの取得および開放をしないとその処理中残り続ける

メモリの確保

  • new : C言語では種類がいくつかあったが、C++だとnewという単語だけで済む
int* ptr = new int; // int型のメモリを1つ確保
*ptr = 10;

int* arr = new int[10]; // int型の配列を10個分確保
for (int i = 0; i < 10; ++i) {
    arr[i] = i;
}

メモリの解放

  • delete : newで確保されたメモリを解放する。単一オブジェクトの場合はdelete、配列の場合はdelete[]を使用する
int* ptr = new int; // int型のメモリを1つ確保
*ptr = 10;
delete ptr; // メモリを解放

int* arr = new int[10]; // int型の配列を10個分確保
for (int i = 0; i < 10; ++i) {
    arr[i] = i;
}
delete[] arr; // 配列のメモリを解放

C#の場合

メモリの確保

new : C++と同じようにnewという単語だけで済む

class MyClass
{
    // クラスのメンバ
}

// メモリの確保
MyClass obj = new MyClass();

メモリの解放

C#では、ガベージコレクタが不要になったオブジェクトを自動的に検出し、メモリを解放する。手動でメモリを解放する必要はない。ただし、ガベージコレクタがいつ実行されるかは保証されていない

ガベージコレクタについては以下のサイトが参考になると思います

参考サイト
[C#][.NET] ガベージコレクタ/ガベージコレクション(GC)に関するまとめ #C# - Qiita
[C#][.NET] ガベージコレクタ/ガベージコレクション(GC)に関するまとめ #C# - Qiita

個人プロジェクトで気軽に C# + WPF を使ってみたら、メモリリークに手ひどくやられたので勉強まとめ.NETにおける ...

続きを読む

メモリ解放の注意点

ガベージコレクタでは管理されないリソース(ファイルハンドル、データベース接続など)を扱う場合、IDisposableインターフェースを実装し、Disposeメソッドを使用してリソースを解放する必要です。usingステートメントを使用すると、スコープを抜けたときに自動的にDisposeメソッドが呼び出されるので管理が楽になります

class MyResource : IDisposable
{
    // リソースの解放処理
    public void Dispose()
    {
        // リソースを解放するコード
        Console.WriteLine("リソースが解放されました");
    }
}

using (MyResource resource = new MyResource())
{
    // リソースを使用する処理
} // ここで自動的にDisposeが呼び出される

ガベージコレクタの強制実行

ガベージコレクタを強制的に実行することもできます。使い道としては、以前このブログでも紹介しているMSのアプリ(Word、Excel、PowerPoint)に対して処理をする際に使用しました

class MyClass
{
    // クラスのメンバ
}

MyClass obj = new MyClass();
// オブジェクトを使用する処理

// 生成したオブジェクトが不要になった場合にガベージコレクションの強制実行
GC.Collect();
GC.WaitForPendingFinalizers();

会社紹介

私が所属しているアドバンスド・ソリューション株式会社(以下、ADS)は一緒に働く仲間を募集しています

会社概要
「技術」×「知恵」=顧客課題の解決・新しい価値の創造

この方程式の実現はADSが大切にしている考えで、技術を磨き続けるgeekさと、顧客を思うloveがあってこそ実現できる世界観だと思っています
この『love & geek』の精神さえあれば、得意不得意はno problem!
技術はピカイチだけど顧客折衝はちょっと苦手。OKです。技術はまだ未熟だけど顧客と知恵を出し合って要件定義するのは大好き。OKです
凸凹な社員の集まり、色んなカラーや柄の個性が集まっているからこそ、常に新しいソリューションが生まれています

ミッション
私たちは、テクノロジーを活用し、業務や事業の生産性向上と企業進化を支援します

ホームページ
アドバンスド・ソリューション株式会社
アドバンスド・ソリューション株式会社

アドバンスド・ソリューションは主にMicrosoft製品を使用して、企業の生産性向上に取り組んでいます。要件定義から導入 ...

サイトへ移動

-プログラム, 技術
-, ,