1
1

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 1 year has passed since last update.

C言語でSTLコンテナ(std::vector)を再現してみる

Last updated at Posted at 2023-03-15

プロローグ

私がこの記事を書こうと思ったきっかけは、あるどこかのプログラミングサイトで「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

最後に

これが最善の方法ではないし、アロケーターを考慮したときに多分やり方とかが変わってくると思うので今後も改良したいと思います。

ありがとうございました。

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?