名前空間
変種
操作

memcpy, memcpy_s

From cppreference.com
< c‎ | string‎ | byte
ヘッダー <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が指すオブジェクトからcount個の文字をdestが指すオブジェクトにコピーします。両方のオブジェクトはunsigned charの配列として解釈されます。
dest配列の末尾を超えてアクセスが発生した場合の動作は未定義です。オブジェクトが重なっている場合(これはrestrict契約の違反です)(C99以降)、動作は未定義です。destまたはsrcが無効なポインタまたはヌルポインタである場合の動作は未定義です。
2) (1)と同じですが、以下のエラーが実行時に検出され、現在の制約ハンドラ関数を呼び出すだけでなく、(destdestszの両方が有効な場合)宛先範囲全体[dest, dest+destsz)がゼロで埋められます。
  • destまたはsrcがヌルポインタである
  • destszまたはcountRSIZE_MAXより大きい
  • countdestszより大きい(バッファオーバーフローが発生する)
  • ソースと宛先のオブジェクトが重なっている
destが指す文字配列のサイズがcountより小さく、かつcountdestsz以下である場合(言い換えれば、destszの誤った値が差し迫ったバッファオーバーフローを露呈しない場合)の動作は未定義です。
すべての境界チェック関数と同様に、memcpy_sは、実装が__STDC_LIB_EXT1__を定義し、ユーザーが<string.h>をインクルードする前に__STDC_WANT_LIB_EXT1__を整数定数1に定義した場合にのみ利用可能であることが保証されます。

目次

[編集] パラメータ

dest - コピー先のオブジェクトへのポインタ
destsz - 宛先で変更する最大バイト数(通常、宛先オブジェクトのサイズ)
src - コピー元のオブジェクトへのポインタ
count - count

[編集] 戻り値

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

[編集] 備考

memcpyは、アロケーション関数によって取得されたオブジェクトの実効型を設定するために使用できます。

memcpyは、メモリ間コピーのための最も高速なライブラリルーチンです。通常、コピーするデータをスキャンする必要があるstrcpyや、重なり合う入力を処理するための予防措置を講じる必要があるmemmoveよりも効率的です。

いくつかのCコンパイラは、適切なメモリコピーループをmemcpy呼び出しに変換します。

厳密なエイリアシングが同じメモリを2つの異なる型の値として調査することを禁じている場合、memcpyは値を変換するために使用できます。

[編集]

#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標準 (ISO/IEC 9899:2011)
  • 7.24.2.1 The memcpy function (p: 362)
  • K.3.7.1.1 The memcpy_s function (p: 614)
  • C99標準 (ISO/IEC 9899:1999)
  • 7.21.2.1 The memcpy function (p: 325)
  • C89/C90標準 (ISO/IEC 9899:1990)
  • 4.11.2.1 The memcpy function

[編集] 関連項目

指定された区切り文字で停止しながら、あるバッファを別のバッファにコピーする
(関数) [編集]
あるバッファを別のバッファに移動する
(関数) [編集]
オーバーラップしていない2つの配列間で、指定された数のワイド文字をコピーする
(関数) [編集]
English 日本語 中文(简体) 中文(繁體)