Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> การเขียนโปรแกรม C

ฟังก์ชัน memcpy() ใน C/C++: คัดลอกหน่วยความจำ

ฟังก์ชัน memcpy() ใช้คัดลอกบล็อกหน่วยความจำ (Memory Block) จาก Source ไป Destination โดยไม่ตรวจสอบ Overlap อยู่ใน Header <string.h>

ไวยากรณ์

#include <string.h>
void *memcpy(void *dest, const void *src, size_t n);
  • dest - Pointer ไปยัง Destination Buffer
  • src - Pointer ไปยัง Source Buffer
  • n - จำนวน Bytes ที่จะคัดลอก
  • คืนค่า: dest (เพื่อ Chaining)

ตัวอย่าง

#include <stdio.h>
#include <string.h>

int main() {
    char src[] = "Secondstring";
    char dest[] = "Firststring";  // ขนาด 12 chars (รวม \0)
    
    // คัดลอก 5 bytes แรกจาก src ไป dest
    memcpy(dest, src, 5);
    
    printf("New arrays: %s\t%s\n", dest, src);
    return 0;
}

ผลลัพธ์

New arrays: Seconstring  Secondstring

คำอธิบาย

  • dest เดิม: "Firststring\0" (12 bytes)
  • src: "Secondstring\0" (13 bytes)
  • memcpy(dest, src, 5) คัดลอก 'S','e','c','o','n' (5 bytes)
  • dest กลายเป็น: "Secondstring" (แต่ 'string' เหลือจากเดิม)

ข้อควรระวังสำคัญ: Overlapping Memory

memcpy() ไม่รับประกันการทำงานถูกต้องเมื่อ Source และ Destination Overlap กัน

// ОПАСНО - Undefined Behavior!
char str[] = "HelloWorld";
memcpy(str + 2, str, 5);  // Overlap! src=str, dest=str+2

// ใช้ memmove() แทนสำหรับ Overlapping Regions

memcpy() vs memmove() vs strcpy()

ฟังก์ชันOverlap SafeNull Terminatorใช้สำหรับ
memcpy()✗ ไม่ไม่สนใจ (Copy Bytes)Raw Memory, Structs, Arrays, Known Size
memmove()✓ ใช่ไม่สนใจOverlapping Regions
strcpy()✗ ไม่Copy จนเจอ \0 (รวม \0)C Strings (Null-terminated)
strncpy()✗ ไม่Copy n chars (อาจไม่มี \0)Fixed-width Fields

การใช้งานทั่วไป

1. Copy Structs/Arrays

struct Point { int x, y; };
struct Point p1 = {10, 20}, p2;
memcpy(&p2, &p1, sizeof(struct Point));

2. Serialize/Deserialize

uint32_t val = 0x12345678;
char buffer[4];
memcpy(buffer, &val, 4);  // Serialize to bytes

3. Fast Array Copy

int src[1000], dest[1000];
memcpy(dest, src, sizeof(src));  // เร็วกว่าลูป for

Performance Notes

  • Compiler มัก Optimize memcpy ให้เป็น Vectorized Instructions (SSE/AVX/NEON)
  • สำหรับขนาดเล็ก (≤ 16 bytes) อาจ Inline เป็น Move Instructions
  • memcpy เร็วกว่า Manual Loop มากในกรณีทั่วไป

ข้อผิดพลาดที่พบบ่อย

  • ลืม Include <string.h>
  • คัดลอกเกินขนาด Destination Buffer (Buffer Overflow)
  • ใช้กับ Overlapping Regions (ใช้ memmove แทน)
  • คาดหวังให้ Null-terminate String (memcpy ไม่ทำ)

สรุป

memcpy() เป็นฟังก์ชันคัดลอก Memory Block พื้นฐาน เร็วและมีประสิทธิภาพ แต่ห้ามใช้กับ Overlapping Memory ใช้ memmove() แทนในกรณีนั้น สำหรับ Strings ใช้ strcpy()/strncpy()