memset, memset_s
提供: cppreference.com
<tbody>
</tbody>
| ヘッダ <string.h> で定義
|
||
void *memset( void *dest, int ch, size_t count ); |
(1) | |
errno_t memset_s( void *dest, rsize_t destsz, int ch, rsize_t count ); |
(2) | (C11以上) |
1) 値
ch ((unsigned char)ch によって行われたかのように unsigned char に変換した後) を dest の指すオブジェクトの先頭 count 文字それぞれにコピーします。dest 配列の終端を超えてアクセスが発生する場合、動作は未定義です。 dest がヌルポインタの場合、動作は未定義です。2) (1) と同じですが、以下のエラーが実行時に検出され、
dest および destsz 自身が有効であれば範囲 [dest, dest+destsz) のすべての位置に ch を格納した後、現在設定されている制約ハンドラ関数を呼びます。
destがヌルポインタ。destszまたはcountが RSIZE_MAX より大きい。countがdestszより大きい (バッファオーバーフローが発生する)。
dest の指す文字配列のサイズ < count <= destsz の場合、動作は未定義です。 別の言い方をすると、誤った destsz の値は切迫したバッファオーバーフローを露呈しません。
- すべての境界チェック付き関数と同様に、
memset_sは__STDC_LIB_EXT1__が処理系によって定義されていて、<string.h>をインクルードする前にユーザが__STDC_WANT_LIB_EXT1__を整数定数 1 に定義した場合にのみ、利用可能であることが保証されます。
引数
| dest | - | 埋めるオブジェクトを指すポインタ |
| ch | - | 埋めるバイト |
| count | - | 埋めるバイト数 |
| destsz | - | dest 配列のサイズ
|
戻り値
1)
dest のコピー。2) 成功した場合はゼロ、エラーが発生した場合は非ゼロ。 また、エラーの場合、
dest がヌルポインタでなく destsz が有効であれば、 destsz 個のバイト ch を dest 配列に書き込みます。ノート
memset は、この関数によって変更されるオブジェクトがその生存期間の残りの間再びアクセスされない場合、 (as-if ルールの下で) 最適化により削除される可能性があります (gcc bug 8537)。 そのため、この関数はメモリを洗浄するために (例えば、パスワードを格納した配列をゼロで埋めるために) 使用することはできません。 この最適化は memset_s に対しては禁止されています。 memset_s はメモリ書き込みを行うことが保証されています。 サードパーティの解決には FreeBSD の explicit_bzero、 Microsoft の SecureZeroMemory などがあります。
例
Run this code
#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
参考文献
- 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 standard (ISO/IEC 9899:1999):
- 7.21.6.1 The memset function (p: 333)
- C89/C90 standard (ISO/IEC 9899:1990):
- 4.11.6.1 The memset function
関連項目
(C11) |
バッファを別のバッファへコピーします (関数) |
(C95) |
ワイド文字配列のすべての位置に指定されたワイド文字をコピーします (関数) |
memset の C++リファレンス
| |