0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

malloc/free時のオーバーヘッドを最小化する方法

Posted at

目的

 malloc/free関数を使用する場合に、オーバーヘッド(負荷)を最小化する方法について、理解する。

内容

 構造体用のメモリ(インスタンス)の割り当てと解放を繰り返す場合、オーバーヘッドが生じてしまう恐れがある。
そのため、構造体用のインスタンスをリストで管理することで、改善する。

  • 構造体のインスタンスが不要の場合は、インスタンスをリストに保存しておく
  • 構造体のインスタンスが必要な場合は、リストからインスタンスを使用する
  • リストに何もない(インスタンスが全て使用されている)場合は、新しいインスタンスを作成する

以下のプログラムを用いて説明する。

  • 構造体の定義
/* test6.h */
#include <stdio.h>

typedef struct _person{
    char* firstName;
    char* lastName;
    char* title;
    unsigned int age;
} Person;
  • メイン処理
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "test6.h"

#define LIST_SIZE 1
Person *list[LIST_SIZE];

/* プロトタイプ宣言 */
void initialiseList();
Person* getPerson();
void initializePerson(Person *person, const char* fn,
    const char* ln, const char* title, unsigned int age);
void deallocatePerson(Person *person);
void displayPerson(Person *person);
Person* returnPerson(Person *person);

int main(void){
    initialiseList();
    Person* ptrPerson;

    ptrPerson = getPerson();
    initializePerson(ptrPerson, "Ralph", "Fitsgerald", "Mr.", 35);
    displayPerson(ptrPerson);
    returnPerson(ptrPerson);
    return 0;
}

void initialiseList(){
    for(int i = 0; i < LIST_SIZE; i++){
        list[i] = NULL;
    }
}

Person* getPerson(){
    for(int i = 0; i < LIST_SIZE; i++){
        if(list[i] != NULL){
            Person* ptr = list[i];
            list[i] = NULL;
            return ptr;
        }
    }
    Person* person = (Person*)malloc(sizeof(Person));
    return person;
}

void initializePerson(Person *person, const char* fn,
    const char* ln, const char* title, unsigned int age){
    person->firstName = (char*)malloc(strlen(fn)+1);
    strcpy(person->firstName, fn);
    person->lastName = (char*)malloc(strlen(ln)+1);
    strcpy(person->lastName, ln);
    person->title = (char*)malloc(strlen(title)+1);
    strcpy(person->title, title);
    person->age = age;
}

void deallocatePerson(Person *person){
    free(person->firstName);
    free(person->lastName);
    free(person->title);
}

void displayPerson(Person *person){
    printf("%s %s, %s, %d\n", person->firstName, person->lastName, person->title, person->age);
}

Person* returnPerson(Person *person){
    for(int i = 0; i < LIST_SIZE; i++){
        if(list[i] == NULL){
            list[i] = person;
            return person;
        }
    }
    deallocatePerson(person);
    free(person);
    return NULL;
}

プログラムの流れを説明する。

  • リストの定義:構造体Person型のリスト配列ポインタを定義する
    • #define LIST_SIZE 1:リストに保存するインスタンスの数1
    • Person *list[LIST_SIZE]:構造体Person型のリスト配列
  • メイン関数
    1. nitialiseList関数でリストを初期化→インスタンスが作成されていない状態
    2. 構造体Person型のポインタptrPersonを作成
    3. ptrPersonにgetPerson関数の返り値が代入される
      ・ リストに構造体がある場合は、構造体Person型のポインタptrにリストが代入され、そのリストはNULLになる→リストからインスタンスが使用される
      ・ リストに何もない場合は、構造体Person型のポインタpersonにメモリが確保される→新しいインスタンスが作成される
    4. initializePerson関数でptrPersonの指す構造体Personのメンバ変数に値が代入される
    5. displayPerson関数でptrPersonの指す構造体Personの中身を表示
    6. returnPerson関数の実行
      ・ リストに何もない場合は、リストに構造体Person型のポインタpresonが代入される
      ・ リストが全て使用されている場合は、構造体Person型のポインタpersonのインスタンスを解放する

所感

malloc、free関数をたくさん使用すると、メモリ容量が減ってしまい、容量が無駄になる。そのため、リストを作成することによって、必要な分だけインスタンスを作成し、リストの上限になるとインスタンスを解放することで、メモリ容量の効率化につながると感じた。

参照

詳説Cポインタ P152、153

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?