1
Sự khác nhau giữa sao chép cạn và sao chép sâu trong lập trình là gì?
1
1
minhkiet150 đã đăng:

Giả sử bạn có 2 đối tượng A và B, khi thực hiện sao chép đối tượng A sang đối tượng B hoặc ngược lại, sẽ xảy ra hai trường hợp sao chép như sau,

Sao chép cạn là trường hợp hai đối tượng A và B có cùng chung một địa chỉ trong vùng nhớ sau khi sao chép, điều này có nghĩa là A và B cùng chia sẻ chung một nội dung (dữ liệu) nằm trong vùng nhớ đó, nếu A chỉnh sửa nội dung thì B cũng bị thay đổi và ngược lại.

Sao chép cạn hai đối tượng trong lập trình

Ví dụ mã nguồn (mình sử dụng Python cho dễ biểu diễn nhé, các ngôn ngữ khác mặc dù cú pháp khác một chút nhưng ý tưởng thì tương tự).

A = [1] # Khởi tạo mảng A chứa 1 phần tử A[0] = 1
B = [2] # Khởi tạo mảng A chưa 1 phần tử B[0] = 2

print id(A) # Địa chỉ vùng nhớ của A là 55500744
print id(B) # Địa chỉ vùng nhớ của B là 40985096

A = B // Sao chép B sang A, đang thực hiện sao chép cạn

print id(A) # Địa chỉ vùng nhớ hiện tại của A là 40985096
print id(B) # Địa chỉ vùng nhớ hiện tại của B là 40985096

id(A) == id(B) # True, A và B có cùng chung địa chỉ vùng nhớ

A[0] = 5 # Nếu A chỉnh sửa phần tử trong vùng nhớ
print B[0] #  B cũng bị thay đổi = 5.

Sao chép sâu là trường hợp hai đối tượng A và B có địa chỉ vùng nhớ riêng sau khi sao chép, điều này có nghĩa là sau này, A và B không còn liên quan gì với nhau nữa, mọi sự thay đổi của A không ảnh hưởng gì tới B và ngược lại.

Sao chép sâu trong lập trình

Ví dụ mã nguồn,

A = [1] # Khởi tạo mảng A chứa 1 phần tử A[0] = 1
B = [2] # Khởi tạo mảng A chưa 1 phần tử B[0] = 2

print id(A) # Địa chỉ vùng nhớ của A là 52016840
print id(B) # Địa chỉ vùng nhớ của B là 52010056

import copy
A = copy.deepcopy(B) // Sao chép B sang A, đang thực hiện sao chép sâu

print id(A) # Địa chỉ vùng nhớ hiện tại của A là 52007688
print id(B) # Địa chỉ vùng nhớ hiện tại của B là 52010056

id(A) == id(B) # False, A và B không còn chung vùng nhớ nữa

A[0] = 5 # Nếu A chỉnh sửa phần tử trong vùng nhớ
print B[0] #  Chẳng liên quan gì tới B, B vẫn giữ nguyên và bằng = 2

Rất cảm ơn câu trả lời của bạn, theo mình nghĩ thì bản chất của sao chép là việc tạo ra một bản sao khác của đối tượng, tất nhiên bản sao thì cần phải độc lập với đối tượng, vậy tại sao người ta không dùng sao chép sâu luôn mà phải tạo thêm dạng sao chép cạn như vậy ạ?

AnCs85 19.08.2018

Nếu bạn chỉ sử dụng sao chép sâu, mỗi lần sao chép lại phải một lần tạo ra vùng nhớ mới, không phải trường hợp nào cũng cần thiết khi tạo ra vùng nhớ mới độc lập, điều này sẽ gây lãng phí tài nguyên bộ nhớ khi chạy chương trình.

Cho nên, sao chép cạn được sử dụng để tăng hiệu quả sử dụng bộ nhớ, nếu hai đối tượng A và B có dữ liệu giống nhau, tại sao không trỏ hai đối tượng A và B tới cùng chung một nơi chứa dữ liệu đó mà phải tạo ra hai nơi độc lập cho cùng một dữ liệu để làm gì đúng không nào.

minhkiet 19.08.2018
thêm bình luận...
Bạn đang thắc mắc? Ghi câu hỏi của bạn và đăng ở chế độ cộng đồng (?)