memcpy, memcpy_s
提供: cppreference.com
ヘッダ <string.h> で定義
|
||
(1) | ||
void* memcpy( void *dest, const void *src, size_t count ); |
(C99未満) | |
void* memcpy( void *restrict dest, const void *restrict src, size_t count ); |
(C99以上) | |
errno_t memcpy_s( void *restrict dest, rsize_t destsz, const void *restrict src, rsize_t count ); |
(2) | (C11以上) |
1)
src
の指すオブジェクトから dest
の指すオブジェクトに count
個の文字をコピーします。 どちらのオブジェクトも unsigned char の配列として解釈されます。dest
配列の終端を超えてアクセスが発生する場合、動作は未定義です。 オブジェクトがオーバーラップしている場合 (これは restrict の契約違反です) (C99以上)、動作は未定義です。 dest
または src
が無効またはヌルポインタの場合、動作は未定義です。2) (1) と同じですが、以下のエラーが実行時に検出され、 (
dest
と destsz
がどちらも有効であれば) コピー先の範囲 [dest, dest+destsz) 全体がゼロクリアされ、現在設定されている制約ハンドラ関数を呼びます。
-
dest
またはsrc
がヌルポインタ。 -
destsz
またはcount
が RSIZE_MAX より大きい。 -
count
がdestsz
より大きい (バッファオーバーフローが発生する)。 - コピー元とコピー先のオブジェクトがオーバーラップしている。
-
dest
の指す文字配列のサイズ < count
<= destsz
の場合、動作は未定義です。 別の言い方をすると、誤った destsz
の値は切迫したバッファオーバーフローを露呈しません。
- すべての境界チェック付き関数と同様に、
memcpy_s
は __STDC_LIB_EXT1__ が処理系によって定義されていて、<string.h>
をインクルードする前にユーザが __STDC_WANT_LIB_EXT1__ を整数定数 1 に定義した場合にのみ、利用可能であることが保証されます。
目次 |
[編集] 引数
dest | - | コピー先のオブジェクトを指すポインタ |
destsz | - | コピー先の変更する最大バイト数 (一般的にはコピー先オブジェクトのサイズ) |
src | - | コピー元のオブジェクトを指すポインタ |
count | - | コピーするバイト数 |
[編集] 戻り値
1)
dest
のコピーを返します。2) 成功した場合はゼロ、エラーが発生した場合は非ゼロの値を返します。 また、エラーの場合、
dest
がヌルポインタでなく destsz
が有効であれば、 destsz
個のゼロのバイトをコピー先の配列に書き込みます。[編集] ノート
memcpy
は確保関数で取得したオブジェクトの実効型を設定するために使用することができます。
memcpy
はメモリからメモリへのコピーのための最も高速なライブラリルーチンであることが意図されています。 通常、コピーするデータをスキャンしなければならない strcpy や、オーバーラップする入力を処理するための予防措置を取らなければならない memmove よりも、効率的です。
一部の C++ コンパイラは、適したメモリコピーループを memcpy
の呼び出しに変換します。
厳格なエイリアシングにより同じメモリを2つの異なる型の値として調べることが禁止される場合に、値を変換するために memcpy
を使用することができます。
[編集] 例
Run this code
#define __STDC_WANT_LIB_EXT1__ 1 #include <stdio.h> #include <stdint.h> #include <inttypes.h> #include <string.h> #include <stdlib.h> int main(void) { // simple usage char source[] = "once upon a midnight dreary...", dest[4]; memcpy(dest, source, sizeof dest); for(size_t n = 0; n < sizeof dest; ++n) putchar(dest[n]); // setting effective type of allocated memory to be int int *p = malloc(3*sizeof(int)); // allocated memory has no effective type int arr[3] = {1,2,3}; memcpy(p,arr,3*sizeof(int)); // allocated memory now has an effective type // reinterpreting data double d = 0.1; // int64_t n = *(int64_t*)(&d); // strict aliasing violation int64_t n; memcpy(&n, &d, sizeof d); // OK printf("\n%a is %" PRIx64 " as an int64_t\n", d, n); #ifdef __STDC_LIB_EXT1__ set_constraint_handler_s(ignore_handler_s); char src[] = "aaaaaaaaaa"; char dst[] = "xyxyxyxyxy"; int r = memcpy_s(dst,sizeof dst,src,5); printf("dst = \"%s\", r = %d\n", dst,r); r = memcpy_s(dst,5,src,10); // count is greater than destsz printf("dst = \""); for(size_t ndx=0; ndx<sizeof dst; ++ndx) { char c = dst[ndx]; c ? printf("%c", c) : printf("\\0"); } printf("\", r = %d\n", r); #endif }
出力例:
once 0x1.999999999999ap-4 is 3fb999999999999a as an int64_t dst = "aaaaayxyxy", r = 0 dst = "\0\0\0\0\0yxyxy", r = 22
[編集] 参考文献
- C11 standard (ISO/IEC 9899:2011):
- 7.24.2.1 The memcpy function (p: 362)
- K.3.7.1.1 The memcpy_s function (p: 614)