【第1部】C言語(K&R検証)編
0030.メモリプールを作成する
今項では
メモリプールの作成を行います。
C/C++では、新しいデータ領域(ヒープ領域)を必要とするときは
malloc()関数か
new演算子を使うのが一般的です。
しかし、これらの処理は
OSに対して新たな領域を要求するという、結構、重い処理になります。
そのため
スピード重視のソフトでは、あらかじめ、大きな領域を確保しておき、各処理などで必要になったときに、そのプールから一部を取得し、いらなくなったらかえす、という処理をする場合があります。
このサンプルはその中でも
後入れ先出しの
スタックのような処理が必要ですが、
メモリプールの概要を説明するには十分です。
きちんとした
メモリプールの実装は後ほど出てきます。
ソース紹介
このサンプルは
project/Sample0030_1に
VS2019のソリューションがあります。もしほかのバージョンの場合は
C++コンソールアプリを作成の上、以下のファイルを作成してください。
CPPファイルに記述
function.h
#pragma once
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cctype>
using namespace std;
char* alloc(int n);
void afree(char* p);
alloc.cpp
#include "function.h"
#define ALLOCSIZE 10000
static char allocbuff[ALLOCSIZE];
static char* allocp = allocbuff;
char* alloc(int n) {
if (allocbuff + ALLOCSIZE - allocp >= n) {
allocp += n;
return allocp - n;
}
else {
return nullptr;
}
}
void afree(char* p) {
if (p >= allocbuff && p < allocbuff + ALLOCSIZE) {
allocp = p;
}
}
main.cpp
#include "function.h"
/*
文字列をtからsにコピーする(ポインタ版3)
*/
void strcpy2(char* s, const char* t) {
while (*s++ = *t++)
;
}
void printarr(char** parr) {
while (*parr != nullptr) {
cout << *parr << endl;
parr++;
}
cout << endl;
}
int main()
{
char* parray[6]{};
char buff[10];
for (int i = 0; i < 5; i++) {
parray[i] = alloc(10);
sprintf_s(buff, "hello%d", i);
strcpy2(parray[i], buff);
printarr(parray);
}
cout << "-------------"<< endl;
for (int i = 4; i >= 0; i--) {
afree(parray[i]);
parray[i] = nullptr;
printarr(parray);
}
return 0;
}
出力
hello0
hello0
hello1
hello0
hello1
hello2
hello0
hello1
hello2
hello3
hello0
hello1
hello2
hello3
hello4
-------------
hello0
hello1
hello2
hello3
hello0
hello1
hello2
hello0
hello1
hello0
サンプル説明
このサンプルは
alloc()関数および
afree()関数の動きを検証するものです。
main()関数を見ていただくとわかりますが
という
ポインタの配列をあらかじめ用意し
alloc()関数で取得した領域のポインタを保存します。その際その内容に
sprintf_s(buff, "hello%d", i);
で作成される文字列をコピーしておきます。
領域は、1つ取得するたびに
printarr()関数で表示します。そこの途により、1つ1つ領域が増えていくのがわかります。
領域の解放の場合は、逆の順番で開放していきます。1つ1つ領域が解放されるたびに、
printarr()関数で表示します。そのため領域が減っていくのがわかります。
K&Rでの記述
元になったのは
第5章:ポインタと配列に記述されています。
アドレス計算の説明のところです。