名稱空間
變體
操作

memcpy, memcpy_s

來自 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 起),則行為未定義。如果 destsrc 是無效或空指標,則行為未定義。
2)(1),除了在執行時檢測到以下錯誤,並導致整個目標範圍 [dest, dest+destsz) 被清零(如果 destdestsz 都有效),並且呼叫當前安裝的約束處理函式
  • destsrc 是空指標
  • destszcount 大於 RSIZE_MAX
  • count 大於 destsz(會發生緩衝區溢位)
  • 源物件和目標物件重疊
如果 dest 指向的字元陣列大小 < count <= destsz,則行為未定義;換句話說,destsz 的錯誤值不會暴露即將發生的緩衝區溢位。
與所有進行邊界檢查的函式一樣,僅當實現定義了 __STDC_LIB_EXT1__ 並且使用者在包含 <string.h> 之前將 __STDC_WANT_LIB_EXT1__ 定義為整數常量 1 時,才保證 memcpy_s 可用。

目錄

[編輯] 引數

dest - 指向要複製到的物件的指標
destsz - 在目標中修改的最大位元組數(通常是目標物件的大小)
src - 指向要從中複製的物件的指標
count - 要複製的位元組數

[編輯] 返回值

1) 返回 dest 的副本。
2) 成功時返回零,錯誤時返回非零值。此外,在錯誤時,如果 dest 不是空指標且 destsz 有效,則在目標陣列中寫入 destsz 個零位元組。

[編輯] 注意

memcpy 可用於設定透過分配函式獲得物件的有效型別

memcpy 是用於記憶體到記憶體複製的最快庫例程。它通常比必須掃描複製資料的 strcpy 或必須採取預防措施來處理重疊輸入的 memmove 更高效。

一些 C 編譯器會將適當的記憶體複製迴圈轉換為 memcpy 呼叫。

嚴格別名禁止將同一記憶體作為兩種不同型別的值進行檢查時,可以使用 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 memcpy 函式 (p: 362)
  • K.3.7.1.1 memcpy_s 函式 (p: 614)
  • C99 標準 (ISO/IEC 9899:1999)
  • 7.21.2.1 memcpy 函式 (p: 325)
  • C89/C90 標準 (ISO/IEC 9899:1990)
  • 4.11.2.1 memcpy 函式

[編輯] 參閱

將一個緩衝區複製到另一個緩衝區,在指定的分隔符處停止
(函式) [編輯]
將一個緩衝區移動到另一個緩衝區
(函式) [編輯]
(C95 起)(C11 起)
在兩個不重疊的陣列之間複製一定數量的寬字元
(函式) [編輯]
C++ 文件 用於 memcpy
English 日本語 中文(简体) 中文(繁體)