memmove, memmove_s
來自 cppreference.com
定義於標頭檔案 <string.h> |
||
void* memmove( void* dest, const void* src, size_t count ); |
(1) | |
errno_t memmove_s(void* dest, rsize_t destsz, const void* src, rsize_t count); |
(2) | (C11 起) |
1) 從 src 指向的物件複製 count 個字元到 dest 指向的物件。兩個物件都被解釋為 unsigned char 陣列。物件可以重疊:複製發生的方式,就好像字元被複制到一個臨時字元陣列,然後字元從該陣列複製到 dest。
如果訪問超出 dest 陣列的末尾,則行為未定義。如果 dest 或 src 是無效指標或空指標,則行為未定義。
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 時,才保證
memmove_s
可用。
目錄 |
[編輯] 引數
dest | - | 指向要複製到的物件的指標 |
destsz | - | 在目標中修改的最大位元組數(通常是目標物件的大小) |
src | - | 指向要從中複製的物件的指標 |
count | - | 要複製的位元組數 |
[編輯] 返回值
1) 返回 dest 的副本
2) 成功時返回零,錯誤時返回非零值。另外,在錯誤時,如果 dest 不是空指標且 destsz 有效,則在目標陣列中寫入 destsz 個零位元組。
[編輯] 注意
memmove
可用於設定透過分配函式獲得物件的有效型別。
儘管被指定為“彷彿”使用了臨時緩衝區,但此函式的實際實現不會帶來開銷或雙重複制或額外記憶體。一種常見方法(glibc 和 bsd libc)是如果目標在源之前開始,則從緩衝區開頭向前複製位元組;否則從末尾向後複製,並且在完全沒有重疊時回退到更高效的 memcpy。
在嚴格別名禁止以兩種不同型別的值檢查同一記憶體的情況下,memmove
可用於轉換值。
[編輯] 示例
執行此程式碼
#define __STDC_WANT_LIB_EXT1__ 1 #include <inttypes.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { char str[] = "1234567890"; puts(str); memmove(str + 4, str + 3, 3); // copy from [4,5,6] to [5,6,7] puts(str); // 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}; memmove(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; memmove(&n, &d, sizeof d); // OK printf("%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 = memmove_s(dst, sizeof dst, src, 5); printf("dst = \"%s\", r = %d\n", dst, r); r = memmove_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 }
可能的輸出
1234567890 1234456890 0x1.999999999999ap-4 is 3fb999999999999a as an int64_t dst = "aaaaayxyxy", r = 0 dst = "\0\0\0\0\0yxyxy", r = 22
[編輯] 參考
- C23 標準 (ISO/IEC 9899:2024)
- 7.24.2.2 memmove 函式 (p: TBD)
- K.3.7.1.2 memmove_s 函式 (p: TBD)
- C17 標準 (ISO/IEC 9899:2018)
- 7.24.2.2 memmove 函式 (p: 264)
- K.3.7.1.2 memmove_s 函式 (p: 446)
- C11 標準 (ISO/IEC 9899:2011)
- 7.24.2.2 memmove 函式 (p: 363)
- K.3.7.1.2 memmove_s 函式 (p: 615)
- C99 標準 (ISO/IEC 9899:1999)
- 7.21.2.2 memmove 函式 (p: 326)
- C89/C90 標準 (ISO/IEC 9899:1990)
- 4.11.2.2 memmove 函式
[編輯] 另請參閱
(C11) |
將一個緩衝區複製到另一個緩衝區 (函式) |
(C95)(C11) |
在兩個可能重疊的陣列之間複製一定數量的寬字元 (函式) |
C++ 文件 用於 memmove
|