コミュニティ

汎用ポインタ(void *)の使い方

汎用ポインタ(void *)とは

ポインタ(*)型でのみ使用できる、void型の変数のこと。
CやC++などの標準ライブラリで見られる。

汎用という単語の通り、あらゆるポインタ型に変換可能。ポインタ型であればどのような型でも受け取ることができる。

char*型やint*型と異なり対象のサイズがないので用途に応じてキャストして使う。

C 標準ライブラリでの使用例

1. memcpy

srcの先頭からlenバイト分をdestへコピーする関数。
引数のdestとsrcはvoid*型であり、関数内でchar*型にキャストされる。

memcpy.c
void *memcpy(void *dest, const void *src, size_t len)
{
    char *d_cpy;
    const char *s_cpy;

    d_cpy = (char *)dest; //char*型にキャスト
    s_cpy = (const char*)src; //const char*型にキャスト
    while (len--)
        *d_cpy++ = *s_cpy++;
    return (dest);
}

2. memchr

srcの先頭からlenバイト分検索し、文字chがある位置のポインタを返す関数。
引数のsrcがconst void*型であり、関数内でconst char*型にキャストされる。

※const: 中身を書き換えられたくない値に対して書き込み禁止とする修飾子

memchr.c
void *memchr(const void *src, int ch, size_t len)
{
    const char *src_cpy;
    int        count;

    src_cpy = (const char *)src; //const char*型にキャスト
    count = 0;
    while (len--)
    {
        if (src_cpy[count] == ch)
            return ((void *)&src_cpy[count]);
        count++;
    }
    return (NULL);
}

C標準ライブラリのmem-関数では、メモリそのものを処理対象とするため、あらゆる型に対応できるよう汎用ポインタ(void *)型が用いられる。

その特性上、mem-関数は

  • strcpy関数のように戻り値のポインタの終端にnull('¥0')を付与することはない(返すのは文字列ではなくメモリ領域だから)
  • srcの途中にnull('¥0')が含まれていてもコピーや検索を中断しない。

汎用ポインタ(void *)のメリット

  • あらゆる型を出入力に使うことができる
  • ポインタの参照先の型が見えないようにすることでメモリアクセスを制限する
mizcii
M.A. in anthropology → iOS, Cなどなど
ユーザー登録して、Qiitaをもっと便利に使ってみませんか。
  1. あなたにマッチした記事をお届けします
    ユーザーやタグをフォローすることで、あなたが興味を持つ技術分野の情報をまとめてキャッチアップできます
  2. 便利な情報をあとで効率的に読み返せます
    気に入った記事を「ストック」することで、あとからすぐに検索できます
ユーザーは見つかりませんでした