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 指向的物件複製 count 個字元到 dest 指向的物件。兩個物件都被解釋為 unsigned char 陣列。2) 同 (1),除了在執行時檢測到以下錯誤,並導致整個目標範圍 [dest, dest+destsz) 被清零(如果
dest 和 destsz 都有效),並且呼叫當前安裝的約束處理函式-
dest或src是空指標 -
destsz或count大於 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)