プロローグ
私がこの記事を書こうと思ったきっかけは、あるどこかのプログラミングサイトで「C言語でもSTLコンテナ(std::vector)」のような動かすにはどうしたらいいのだろうと思ったからです。
免責事項
本来なら、アロケーターの部分を考慮しなければならないのですが、まずは(実力がない)アロケーターを考慮しないことにします...。
push_back関数を再現してみる
安直に考えたこととしては、stdlib.h に入っているmalloc関数を使ってみることにしました。
main.c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int* array = NULL;
size_t size = 0;
///<summary>
///値を追加する関数
///<summary>
///<param name="index"> 追加いしたい値</param>
///<return>成功・失敗</return>
bool push_back(int value)
{
size++;
// 値を取得する
int* tmp = (int*)realloc(array,size * sizeof(int));
// ヒープ生成に失敗
if(tmp == NULL)
{
return false;
}
// 今までの値を入れる
for(int i = 0;i < size - 1;i++)
{
*(tmp + i) = *(array + i);
}
*(tmp + size - 1) = value;
array = tmp;
return true;
}
erase関数を再現してみる
erase関数は以下のようになると思います。
main.c
///<summary>
///要素を削除
///<summary>
///<param name="index"> 削除したい要素</param>
///<return>成功・失敗</return>
bool erase(int index)
{
if(0 <= index && index < size)
{
int* tmp = (int*)malloc((size - 1) * sizeof(int));
if(tmp == NULL)
{
return false;
}
for(int i = 0;i < size;i++)
{
if(i > index)
{
*(tmp + i - 1) = *(array + i);
}
else
{
*(tmp + i) = *(array + i);
}
}
array = tmp;
size--;
return true;
}
else
{
return false;
}
}
clear関数を再現してみる
clear関数は以下のようになると思います。
main.c
///<summary>
///すべて削除
///<summary>
///<param name="index"> 削除したい要素</param>
///<return>成功・失敗</return>
bool clear()
{
if(array == NULL)
{
return false;
}
array = NULL;
size = 0;
return true;
}
empty関数を再現してみる
empty関数は以下のようになります
main.c
bool empty()
{
return array == NULL ? true : false;
}
試しに使ってみました
以下のように実際に実行してみました
main.c
int main(void)
{
array = malloc(1 * sizeof(int));
if(array == NULL)
{
abort();
}
*(array + 0) = 0;
for(int i = 0;i < 5;i++)
{
push_back(i + 1);
}
erase(2); // 実際に消されているか確認する
erase(-350); // 無効な値を入れてみる
for(int i = 0;i < size;i++)
{
printf("%d\n",*(array + i));
}
clear();
printf("empty %s\n",empty() == true ? "空です。" : "空ではありません");
return 0;
}
実行結果
0
1
3
4
5
empty 空です。
status : 0
最後に
これが最善の方法ではないし、アロケーターを考慮したときに多分やり方とかが変わってくると思うので今後も改良したいと思います。
ありがとうございました。