名前空間
変種
操作

memset, memset_explicit, memset_s

From cppreference.com
< c‎ | string‎ | byte
ヘッダー <string.h> で定義
void *memset( void *dest, int ch, size_t count );
(1)
void *memset_explicit( void *dest, int ch, size_t count );
(2) (C23以降)
errno_t memset_s( void *dest, rsize_t destsz, int ch, rsize_t count );
(3) (C11 以降)
1) 指定されたオブジェクトの先頭countバイトに、chの値((unsigned char)chとして解釈される)をコピーします。
dest配列の終端を超えてアクセスした場合、動作は未定義です。destがヌルポインタの場合、動作は未定義です。
2) (1)と同様ですが、機密情報に対して安全です。
3) (1)と同様ですが、実行時に以下のエラーが検出され、destdestszが有効な場合、指定された範囲[dest, dest+destsz)のすべての場所にchを書き込んだ後、現在インストールされている制約ハンドラ関数が呼び出されます。
  • destがヌルポインタである
  • destszまたはcountRSIZE_MAXより大きい
  • countdestszより大きい(バッファオーバーフローが発生する)
destによって指される文字配列のサイズがcount未満である場合(count <= destsz)、動作は未定義です。つまり、destszの誤った値は、予期されるバッファオーバーフローを露呈しません。
すべての境界チェック関数と同様に、memset_sは、実装によって__STDC_LIB_EXT1__が定義され、ユーザーが<string.h>をインクルードする前に__STDC_WANT_LIB_EXT1__を整数定数1として定義した場合にのみ、利用が保証されます。

目次

[編集] パラメータ

dest - 初期化するオブジェクトへのポインタ
文字 - 埋めるバイト
count - 埋めるバイト数
destsz - 宛先配列のサイズ

[編集] 戻り値

1,2) destのコピー
3) 成功した場合はゼロ、エラーの場合は非ゼロ。また、エラーの場合、destがヌルポインタではなくdestszが有効であれば、宛先配列にdestsz個の埋めバイトchを書き込みます。

[編集] 注記

memsetは、この関数によって変更されたオブジェクトがそのライフタイムの残りの期間アクセスされない場合(例:パスワードを格納した配列をゼロで埋めるために使用できない)、as-ifルールのもとで最適化されて削除される可能性があります(例:gcc bug 8537)。このため、この関数はメモリをスクラブするため(例:パスワードを格納した配列をゼロで埋めるため)には使用できません。

この最適化は、memset_explicitおよびmemset_sでは禁止されています。これらの関数はメモリ書き込みを実行することが保証されています。

これに対するサードパーティのソリューションには、FreeBSDのexplicit_bzeroやMicrosoftのSecureZeroMemoryがあります。

[編集]

#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
int main(void)
{
    char str[] = "ghghghghghghghghghghgh";
    puts(str);
    memset(str,'a',5);
    puts(str);
 
#ifdef __STDC_LIB_EXT1__
    set_constraint_handler_s(ignore_handler_s);
    int r = memset_s(str, sizeof str, 'b', 5);
    printf("str = \"%s\", r = %d\n", str, r);
    r = memset_s(str, 5, 'c', 10);   // count is greater than destsz  
    printf("str = \"%s\", r = %d\n", str, r);
#endif
}

実行結果の例

ghghghghghghghghghghgh
aaaaahghghghghghghghgh
str = "bbbbbhghghghghghghghgh", r = 0
str = "ccccchghghghghghghghgh", r = 22

[編集] 参照

  • C17標準 (ISO/IEC 9899:2018)
  • 7.24.6.1 The memset function (p: 270)
  • K.3.7.4.1 The memset_s function (p: 451)
  • C11標準 (ISO/IEC 9899:2011)
  • 7.24.6.1 The memset function (p: 371)
  • K.3.7.4.1 The memset_s function (p: 621-622)
  • C99標準 (ISO/IEC 9899:1999)
  • 7.21.6.1 The memset function (p: 333)
  • C89/C90標準 (ISO/IEC 9899:1990)
  • 4.11.6.1 The memset function

[編集] 関連項目

あるバッファを別のバッファにコピーする
(関数) [編集]
与えられたワイド文字をワイド文字配列のすべての位置にコピーする
(関数) [編集]
English 日本語 中文(简体) 中文(繁體)