Namespaces
Variants

memset, memset_explicit, memset_s

From cppreference.net
< 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) ( unsigned char ) ch dest が指すオブジェクトの先頭 count 文字の各々にコピーします。
dest配列の終端を超えてアクセスが発生した場合、動作は未定義です。 dest がヌルポインタの場合、動作は未定義です。
2) (1) と同様ですが、機密情報に対して安全である点が異なります。
3) (1) と同様であるが、以下のエラーが実行時に検出され、宛先範囲 [ dest, dest + destsz ) の全位置に ch を格納した後、現在インストールされている 制約ハンドラ 関数を呼び出す( dest destsz 自体が有効な場合):
  • dest がヌルポインタである
  • destsz または count RSIZE_MAX より大きい
  • count destsz より大きい(バッファオーバーフローが発生する)
dest が指す文字配列のサイズが count <= destsz の場合、動作は未定義です。言い換えれば、 destsz の誤った値は差し迫ったバッファオーバーフローを露呈しません。
すべての境界チェック付き関数と同様に、 memset_s は実装によって __STDC_LIB_EXT1__ が定義され、かつユーザーが <string.h> をインクルードする前に __STDC_WANT_LIB_EXT1__ を整数定数 1 に定義した場合にのみ利用可能であることが保証されます。

目次

翻訳の説明: - 「Contents」を「目次」に翻訳しました - HTMLタグ、属性、 内のC++関連用語(Parameters、Return value、Notes、Example、References、See also)は翻訳せずに保持しました - 数値、構造、フォーマットは完全に保持されています - プロフェッショナルな技術文書として適切な日本語表現を使用しています

パラメータ

dest - 埋め込み先オブジェクトへのポインタ
ch - 埋め込みバイト値
count - 埋め込むバイト数
destsz - 宛先配列のサイズ

戻り値

1,2) dest のコピー
3) 成功時はゼロ、エラー時は非ゼロを返す。またエラー時、 dest がnullポインタでなく、 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 memset関数 (p: 270)
  • K.3.7.4.1 memset_s関数 (p: 451)
  • C11 standard (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 memset関数 (p: 333)
  • C89/C90標準 (ISO/IEC 9899:1990):
  • 4.11.6.1 memset関数

関連項目

バッファを別のバッファにコピーする
(関数)
(C95)
指定されたワイド文字をワイド文字配列の全位置にコピーする
(関数)