CHPV C++ | Điểm mấu chốt cần nhớ về memcpy và strcpy

MỤC LỤC:
Ảnh: Điểm mấu chốt cần nhớ về memcpy và strcpy

1. memcpy

#include <string.h>

Tác dụng của hàm là sao chép cụ thể một số lượng byte (soLuongByteCanCopy) byte từ vị trí mà nguồn trỏ tới (nguon) trỏ tới đến vị trí mà đích trỏ tới (destination) trỏ tới. 

Copy chính xác số byte dữ liệu từ vùng nhớ nguồn sang vùng nhớ đích.

void * memcpy( void * dich, const void * nguon, size_t soLuongByteCanCopy );

dich: con trỏ bắt đầu của đích đến

nguon: con trỏ của nguồn ( vị trí bắt đầu copy dữ liệu )

soLuongByteCanCopy: số lượng byte cần copy từ vị trí nguon đến vị trí dich


2. strcpy

#include<cstring>

char* strcpy( char* dich, const char* nguon );

Copy chuỗi ký tự nguồn sang vị trí bắt đầu bởi con trỏ đích. Số lượng byte cần copy được quyết định bởi con trỏ NULL kết thúc của chuỗi cần copy. 

dich: con trỏ bắt đầu của đích đến

nguon: con trỏ của nguồn ( vị trí bắt đầu copy dữ liệu )


3. Ví dụ đặc biệt

3.1. memcpy - Tại sao câu lệnh dưới đây lại không bị lỗi

#include <iostream>
#include <string.h>
#include <cstring>

using namespace std;

int main()
{
    char str1[30] = "tuanTitien chao mung ban";
    char str2[10] = "kem";
    char str3[10] = "chihi";

    cout << "1. str1: " << str1 << endl;;;;
    cout << "1. str2: " << str2 << endl;;;;
    cout << "1. str3: " << str3 << endl;;;;

    memcpy(str2, str1 + 4, 11);

    cout << "2. str1: " << str1 << endl;;;;
    cout << "2. str2: " << str2 << endl;;;;
    cout << "2. str3: " << str3 << endl;;;;
    return 0;
}

Kết quả 

1. str1: tuanTitien chao mung ban
1. str2: kem
1. str3: chihi
2. str1: tuanTitien chao mung ban
2. str2: Titien chaohihi
2. str3: ohihi

Điều đặc biệt ở trong xử lý trên là: 

...
char str2[10] = "kem"; //
...
memcpy(str2, str1 + 4, 11);
...

Ở trong lần chạy này, đoạn code trên vẫn chạy được mà không gây nên lỗi. 
Nhưng không ai có thể đảm bảo được rằng nó có thể gây ra lỗi gì hay không trong trường hợp bộ nhớ hệ thống bị phân mảnh, và con trỏ (str2 + 10) chọc đến một vùng nhớ không thuộc quản lý của process hiện tại của chúng ta ( có thể đang được quản lý bởi một process khác hoặc đang bị hệ điều hành không cho phép can thiệp )

Việc copy  làm ghi đè cả ký tự null '\0' đánh dấu điểm kết thúc của str2 ban đầu {'k', 'e', 'm', '\0'} , dẫn đến khi in ra str2, console đã nhận biết str2 và str3 chung một ký tự null '\0' để kết thúc
1. str2: kem 👉 2. str2: Titien chaohihi

Ở trong trường hợp chạy được này, may mắn (str2 + 10) chọc đến vùng nhớ lưu data cho str3. Dẫn đến: 
1. str3: chihi 👉 2. str3: ohihi

Vậy nên việc sử dụng memcpy cần được xem xét một cách cẩn thận. 

TuanTiTien++

Author:

Tôi là Tuấn Anh, một lập trình viên C++, hiện tại đang làm việc với Qt Framework. Giờ đã là bố của một thanh niên nhỏ, gần đây tôi thấy mình cần sống có trách nhiệm hơn nữa. : ]] Tôi cảm thấy nếu tôi không có nơi nào đó để ghi lại, tôi sẽ quên mất nhiều thứ. Dấu chân trên cát cũng vậy, nếu ta không chụp ảnh nó lại, rồi nó cũng sẽ bị gió làm mờ đi dần rồi mất hút hẳn. Cảm ơn anh em đã ghé qua và đọc những gì tôi viết. Hữu duyên thiên lý Ngô tương nặng, à nhầm Năng tương ngộ. : ]] Thân ái 3000!
© Giao diện website thiết kế bởi TuanTiTien.com