Xin chào và chào mừng. Bây giờ chúng ta đã hiểu về cấp phát bộ
nhớ động, chúng ta phải triển khai nó, chúng ta phải thực sự biết cách thực hiện nó trong mã c.
Vì vậy, chúng ta sẽ nói về ba hàm thực
sự quan trọng, malloc, calloc, realloc.
Bạn thấy rằng chúng sắp xếp có tên mà calloc phân
bổ bộ nhớ và phân bổ lại.
Cách đơn giản và phổ biến nhất để cấp phát bộ nhớ là
thông qua hàm thư viện tiêu chuẩn có tên là malloc.
Đây là cấp phát bộ nhớ động trong thời gian chạy.
Để gọi hàm này, bạn cần phải bao gồm tệp tiêu đề lib tiêu chuẩn.
Bạn chỉ định số byte bộ nhớ mà bạn muốn cấp phát làm đối số của nó.
Những gì trả về từ hàm này là địa chỉ của byte bộ nhớ đầu tiên được cấp phát.
Bởi vì bạn nhận được một địa chỉ được trả về, một con trỏ là nơi duy nhất để đặt nó.
Vì vậy, đây là lý do tại sao cấp phát bộ nhớ động chỉ có thể thực
hiện được thông qua khái niệm con trỏ này vì nó trả về địa chỉ.
Bạn chỉ có thể đặt một địa chỉ trong một con trỏ, đó là những gì một con trỏ lưu trữ, một con trỏ lưu trữ một địa chỉ.
Vì vậy, đây là cách bạn làm điều đó rất đơn giản, cú pháp.
Thông thường, khi tạo con trỏ của bạn, bạn không cần phải làm như vậy.
Bạn có thể tạo con trỏ của mình và đặt nó thành null.
Và sau đó trong dòng tiếp theo, bạn có thể malloc.
Nhưng đây là cú pháp tiêu chuẩn mà bạn đang tạo con trỏ int, con
trỏ tới một kiểu int.
Và sau đó bạn sẽ nhận thấy rằng bạn gọi malloc.
Và ở đây, chúng ta đang nói malloc, chúng ta sẽ tạo 100 byte cho malloc và
sau đó chúng ta sẽ truyền nó tới một con trỏ int.
Bởi vì malloc chỉ trả về một địa chỉ, bạn phải truyền nó đến
một con trỏ kết thúc vì địa chỉ đó đang
lưu trữ một con trỏ int.
Đây là cách tiêu chuẩn để làm điều đó.
Bây giờ bạn đang yêu cầu 100 byte bộ
nhớ và gán nó cho địa chỉ của khối bộ nhớ thành số p.
pNumber sẽ trỏ đến vị trí int đầu tiên ở đầu 100 byte đã được cấp phát.
Vì vậy, điều này có nghĩa là vì các số nguyên có 4 byte một mảnh, nó
có thể chứa 25 giá trị int.
Và một lần nữa, điều này giả sử rằng bạn có 4 byte.
Bây giờ tùy thuộc vào hệ thống mà bạn đang chạy, chúng có thể lớn hơn, có thể nhỏ hơn.
Vì vậy, bạn nên nhìn thấy vấn đề với điều này. Mã này sẽ không hoạt động
trên các hệ thống khác nhau bởi vì bạn đang phân bổ dựa trên một giả định,
dựa trên giả định về kích thước int.
Vì vậy, nó không thực sự tốt khi sử dụng
malloc theo cách này với một số không đổi 100.
Những gì bạn muốn làm là bạn muốn sử dụng toán tử sizeof.
Vì vậy, sẽ tốt hơn nếu loại bỏ giả định rằng int là 4 byte.
Thay vào đó, nếu bạn muốn phân bổ chỗ cho 25 số nguyên bên trong đối số malloc, hãy
chỉ định số lượng số nguyên
bạn muốn phân bổ và sau đó nhân nó với kích thước của các số nguyên.
Và điều này sẽ làm cho mã di động hơn nhiều.
Mã này bây giờ sẽ hoạt động trên các hệ thống khác nhau, hệ điều hành khác nhau, kiến trúc khác nhau.
Bạn vẫn ép giá trị trả về cho địa chỉ vì nó phải trỏ đến
kiểu int, vì vậy bạn nói int star. Sự khác biệt duy nhất ở đây là bạn sử dụng toán tử sizeof.
Toán tử sizeof thực sự quan trọng khi bạn cấp phát bộ nhớ bằng malloc
hoặc sử dụng calloc hoặc realloc.
Bạn luôn sử dụng và muốn sử dụng toán tử
sizeof cho kiểu mà bạn đang phân bổ, sau đó nhân nó với bao
nhiêu số cụ thể bạn muốn, vì vậy nếu bạn muốn lưu
trữ 25 int, thì bạn thực hiện 25.
Vì vậy, đối số của malloc ở trên chỉ ra rõ ràng rằng phải có
đủ byte để chứa 25 giá trị kiểu int.
Ngoài ra, như tôi đã đề cập, hãy để ý dàn diễn viên. Điều này sẽ chuyển đổi địa
chỉ, được hàm trả về kiểu con trỏ thành int và con trỏ int.
Malloc trả về một con trỏ kiểu void, đó là điều khiến nó trở nên rất hữu ích.
Nó trả về địa chỉ đó nhưng nó là một con trỏ vô hiệu.
Hãy nhớ rằng, chúng ta đã nói về con trỏ void và tại sao con trỏ void lại
hữu ích bởi vì bây giờ bạn có thể có một hàm có thể nhận các tham số khác nhau và nó có thể
trả về một con trỏ void. Bây giờ bạn đang thấy sức
mạnh của việc trả về một con trỏ void,
một lần nữa, nhưng để sử dụng nó, để thực sự gán dữ liệu cho nó, để hủy tham chiếu nó, bạn
phải ép kiểu nó.
Nếu chúng tôi không muốn ép kiểu này, chúng tôi có thể nói void star p number.
Chúng tôi không cast nó, nhưng sau đó chúng tôi sẽ phải cast nó một
khi chúng tôi muốn hủy tham chiếu nó.
Nhưng đó là lý do tại sao chúng ta phải cast từ malloc. Nó trả về một địa chỉ và bạn muốn nó
trỏ đến kiểu int và nó trả về kiểu void.
Bạn có thể yêu cầu bất kỳ số lượng byte nào.
Tuy nhiên, nó phụ thuộc vào hệ thống của bạn và bạn có bao nhiêu bộ nhớ trên hệ thống của mình.
Vì vậy, nếu bạn cố gắng tạo hoặc cố gắng yêu cầu hàng tấn byte hoặc có
một số giới hạn, nó có thể không thành công.
Và khi bị lỗi, nó trả về giá trị null, malloc sẽ trả về giá trị null.
Và điều này là tốt vì con trỏ khi con trỏ trỏ đến null, có nghĩa là chúng không trỏ đến
bất kỳ bộ nhớ nào, vì vậy bạn không
thể vô tình làm hỏng hoặc thay đổi bất kỳ bộ nhớ nào.
Vì vậy, việc kiểm tra null ngay lập tức
trước khi sử dụng luôn là một ý kiến hay,
giống như khi bạn gán dữ
liệu hoặc giống như khi bạn hủy tham chiếu một con trỏ.
Bạn muốn chắc chắn rằng bạn đang thực sự chỉ vào một cái gì đó.
Vì vậy, ở đây, chúng tôi đang phân bổ một số bộ nhớ cho số p con trỏ của chúng tôi và
sau đó chúng tôi đang nói nếu không phải là số p.
Hãy nhớ rằng, null là một số không.
Vì vậy, bạn chỉ có thể sử dụng không trên nó. Bạn không cần phải thực sự so sánh nó với null.
Bạn có thể, bạn có thể so sánh nó với null nó làm cho nó dễ đọc hơn, có thể làm cho nó rõ ràng hơn.
Nhưng bạn chỉ có thể nói không phải số p, và điều đó thực sự nói không phải
là một, và null là số không. Vì vậy, điều này sẽ kiểm tra null.
Và nếu nó là null, về cơ bản điều đó có nghĩa là
bộ nhớ không thể được cấp phát. Nếu bạn không thể phân bổ bộ nhớ trong chương trình của mình, bạn đang gặp rắc rối.
Và vì vậy những gì bạn thường làm trong đoạn mã này để đối phó với
lỗi cấp phát bộ nhớ là bạn nên hủy bỏ, bạn nên
gọi thoát, bạn nên thoát khỏi chương trình của mình. Bởi vì nếu chương trình của bạn không thể cấp phát bộ nhớ, chương trình của bạn đã hoạt động.
Vì vậy, thông thường đây là bạn gọi là hủy bỏ do tai nạn nếu bạn không thể cấp phát bộ nhớ.
Ít nhất khi bạn làm điều này, bạn có thể hiển thị thông báo
kết thúc chương trình. Nó tốt hơn nhiều so
với việc cho phép chương trình tiếp tục khi bạn không có, chúng tôi không thể cấp phát bộ nhớ.
Bởi vì sau đó bạn có thể tiếp tục, bạn có thể cố gắng sử dụng
bộ nhớ đó, nó sẽ trống, vì vậy chương trình sẽ gặp sự cố bất cứ lúc
nào nhưng bạn không nhất thiết phải biết tại sao.
Bạn phải nhìn vào ngăn xếp cuộc gọi. Sẽ mất nhiều thời gian hơn để gỡ lỗi đó.
Giải phóng bộ nhớ. Bây giờ tôi đã đề cập rằng
vì bạn là lập trình viên chịu trách nhiệm cấp phát bộ nhớ, bạn phải loại
bỏ bộ nhớ khi bạn không còn sử dụng vì bộ nhớ là tài nguyên quan trọng,
đặc biệt là trên các hệ thống nhúng.
Bạn không nên sử dụng bộ nhớ nếu bạn không cần nó. Vì vậy, bạn phải giải phóng bộ nhớ.
Bạn luôn muốn giải phóng bộ nhớ khi nó không còn cần thiết.
Bộ nhớ mà bạn phân bổ trên heap sẽ tự động được giải phóng khi chương trình của bạn tồn tại, điều này tốt
vì nó thực hiện một số công việc dọn dẹp.
Nhưng tốt hơn hết là giải phóng bộ nhớ một cách rõ ràng khi bạn đã hoàn thành
nó ngay cả khi nó ngay trước khi bạn thoát.
Nó sạch hơn, luôn
luôn làm điều đó miễn phí hoặc luôn giải phóng bộ nhớ sau khi bạn cấp
phát nó, bạn muốn tuân theo quy tắc này. Đây là một quy tắc nghiêm ngặt nghiêm ngặt.
Luôn giải phóng bộ nhớ nếu bạn cấp phát nó.
Rò rỉ bộ nhớ xảy ra khi bạn phân bổ động một số bộ nhớ
và bạn không giữ lại tham chiếu nên bạn không thể giải phóng nó.
Có thể bạn đang ở ngoài phạm vi tham chiếu mà bạn không thể. Bạn không giải phóng nó.
Đó được gọi là rò rỉ bộ nhớ. Có bộ nhớ được cấp phát nhưng nó không còn được sử dụng nữa.
Điều này thường xảy ra khi bạn đang ở trong một vòng lặp và bạn đang cấp phát bộ nhớ trong một vòng lặp.
Bạn đang ở trong vòng lặp. Bạn phân bổ bộ nhớ này. Bạn sử dụng nó bên trong vòng
lặp, và sau đó bạn nhảy ra khỏi vòng lặp và bạn không còn giải phóng nó nữa.
Mỗi lần lặp vòng lặp là cấp phát nó.
Vì vậy, để giải phóng bộ nhớ mà bạn đã cấp phát động, bạn
vẫn phải có quyền truy cập vào địa chỉ đó.
Vì vậy, thông thường bạn muốn có một bộ nhớ trống khi sử dụng xong và thường
là trong phương thức mà bạn đã cấp phát nó.
Tuy nhiên, nếu bạn đang chuyển bộ nhớ đó cho một hàm khác và thì đó
là trách nhiệm của hàm đó, nhưng thông thường bạn muốn giải phóng bộ nhớ và chức
năng mà bạn cấp phát nó.
Để giải phóng bộ nhớ cho một khối bộ nhớ được cấp
phát động có địa chỉ bạn đã lưu trong một con trỏ, tất cả những gì
bạn phải làm là gọi hàm miễn phí.
Điều này cũng nằm trong lib tiêu chuẩn. Bạn chỉ cần chuyển con trỏ đến hàm miễn phí.
Và thông thường, sau khi bạn chuyển con trỏ đó, bạn muốn đặt nó thành null vì
điều đó nói rằng bạn không có bộ nhớ được cấp phát cho nó.
Hàm miễn phí có một tham số chính thức kiểu void star, vì vậy
bạn có thể truyền vào bất kỳ kiểu con trỏ nào
và nó sẽ hoạt động.
Bạn không cần phải cast nó hay bất cứ thứ gì tương tự.
Miễn là số p chứa địa chỉ được trả về khi bộ nhớ được cấp phát, toàn bộ
khối bộ nhớ sẽ được sử dụng miễn phí. Các chương trình khác có thể sử dụng bộ nhớ đó,
chương trình của bạn hiện có thể sử dụng bộ
nhớ đó, rất quan trọng khi bạn đang sử dụng hệ thống nhúng.
Và như tôi đã đề cập, bạn luôn muốn đặt con trỏ thành null
để biểu thị rằng con trỏ đó không còn trỏ đến bất kỳ thứ gì nữa.
Bộ nhớ đó đã được giải phóng.
Có một chức năng hay khác được gọi là calloc.
Điều này có một vài lợi thế so với malloc. Nó rất giống với malloc, nhưng
những gì nó làm là nó phân bổ bộ nhớ dưới dạng một số phần tử có kích thước
nhất định và nó cũng khởi tạo bộ nhớ.
Đó là sự khác biệt, khởi tạo. Tôi đã nói về tầm quan trọng của việc khởi tạo.
Đó là lý do
tại sao bạn luôn muốn khởi tạo dữ liệu để bạn hiểu rằng có dữ liệu
trong đó mà bạn đang mong đợi.
Khi bạn hủy khởi tạo dữ liệu, có thể có dữ liệu trong đó mà bạn không có bất kỳ manh mối nào.
Vì vậy, hãy luôn khởi tạo dữ liệu của bạn bằng một thứ gì đó.
Và calloc tốt hơn một chút vì nó làm điều đó cho bạn.
Nó có hai đối số, có hai tham số.
Số lượng mục dữ liệu cần có dung lượng, kích thước của từng mục dữ liệu.
Nó được khai báo trong tiêu đề lib tiêu chuẩn.
Bạn gọi nó giống như bạn gọi malloc. Trông khá giống nhau.
Trong ví dụ này, chúng tôi đang tạo một con
trỏ số nguyên và chúng tôi đang phân bổ 75 số nguyên
của sizeof int. Vì vậy, nó có hai tham số.
Nó gọn gàng hơn một chút vì bạn không phải thực hiện phép nhân.
Trong malloc, bạn phải thực hiện 75 sự kiện kích thước thời gian.
Ở đây bạn chỉ cần nói 75,
bạn đang tạo 75 int và kích thước cho mỗi int là 4 byte hoặc bất
kỳ thứ gì hệ thống trả về từ kích thước của toán tử.
Nhưng một lần nữa ý nghĩa của điều này là nó cũng sẽ khởi tạo tất cả dữ liệu đó, giá
trị trả về có thể là null nếu nó không thể cấp phát bộ nhớ đó, do đó bạn không nên hủy bỏ.
Nhưng nó rất giống với việc sử dụng malloc ngoại trừ điểm cộng lớn là khởi tạo này.
Tất cả các int được khởi tạo bằng 0, và đó thực sự là một vấn đề lớn,
một lợi thế lớn.
Nó cũng dễ sử dụng hơn một chút với hai tham số.
Hãy nói về một hàm khác được gọi là realloc.
Hàm realloc cho phép bạn sử dụng lại hoặc mở rộng bộ nhớ mà bạn đã cấp phát
trước đó bằng cách sử dụng malloc hoặc calloc.
Vì vậy, đây là một cách để thay đổi động lượng bộ nhớ được cấp phát
trong khi bạn đang chạy.
Vì vậy, ban đầu bạn có thể tạo ra rất nhiều bộ nhớ và sau đó bạn nhận
ra rằng, đó là bộ nhớ không đủ. Vâng, những gì bạn có thể làm ở đó là bạn có thể
gọi realloc, và điều này sẽ phân bổ lại bộ nhớ.
Nó mong đợi hai giá trị đối số, một con trỏ chứa địa chỉ mà
trước đó đã được chuyển bởi một cuộc gọi tới malloc.
Vì vậy, bạn có một con trỏ có một số bộ nhớ được cấp phát hoặc calloc và sau đó
là kích thước và byte của bộ nhớ mới mà bạn muốn cấp phát nó.
Vì vậy, điều này sẽ phân bổ lượng bộ nhớ mà bạn chỉ định bởi đối số
thứ hai, đó là đối số thứ hai. Nó chuyển nội dung của bộ nhớ được cấp phát
trước đó, được tham chiếu bởi con trỏ, vì vậy nó tự động biết bạn đã cấp phát
bao nhiêu bộ nhớ trước đó vì bạn chuyển vào con trỏ.
Và sau đó nó sẽ thực sự thêm vào đó, bộ nhớ mới được cấp phát.
Và nó trả về một con trỏ void vào bộ nhớ mới.
Vì vậy, bạn phải đúc lại nó khi bạn gọi realloc giống như những cái khác.
Nó trả về null nếu bạn không thể phân bổ lại, đây
có thể là một lỗi nghiêm trọng và bạn nên hủy bỏ.
Tính năng quan trọng nhất của thao tác này là phân
bổ lại bảo toàn nội dung của vùng bộ nhớ ban đầu, bạn chỉ mở rộng bộ nhớ đó.
Nó có thể bị phân mảnh vì bạn có thể không thực hiện được theo trình tự, nhưng bạn
vẫn có tất cả bộ nhớ mà bạn có thể gán cho dữ liệu bây giờ.
Hãy xem một ví dụ.
Trong ví dụ này, chúng ta sẽ sử dụng malloc và sau đó chúng ta sẽ phân bổ lại bộ nhớ và sau đó
chúng ta sẽ giải phóng nó.
Vì vậy, ở đây chúng tôi đang tạo một con trỏ ký tự.
Chúng tôi không khởi tạo nó thành null, có lẽ chúng tôi nên làm như vậy.
Nhưng nó không có bất kỳ bộ nhớ nào được cấp phát cho những gì nó trỏ tới.
Nó có bộ nhớ được cấp phát để lưu
trữ con trỏ, chỉ là một địa chỉ. Nhưng nếu bạn cố gắng đi đến địa chỉ đó, chương trình của bạn sẽ được lưu trữ.
Vì vậy, những gì bạn làm là bạn gọi là malloc.
Ở đây chúng tôi đang nói malloc 15.
Điều này sẽ tạo 15 byte cho một con trỏ ký tự.
Chúng tôi ép kiểu nó, vì nó trả về một con trỏ void. Vì vậy, str là một con trỏ
bây giờ có bộ nhớ được cấp phát cho những gì nó trỏ tới.
Sau đó, chúng tôi có thể sử dụng bản sao str để chuyển một số dữ liệu đến những
gì nó trỏ đến, một chuỗi và
chúng tôi in ra chuỗi trong địa chỉ.
Chà, sau đó chúng tôi nhận ra rằng những gì chúng tôi đã phân bổ 15
byte là không đủ lớn.
Vì vậy, sau đó chúng ta gọi realloc, và chúng
ta truyền vào con trỏ là str và chúng ta muốn phân bổ lại 25 byte nữa và sau đó nó
trả về một điểm trống vì chúng ta phải ép kiểu lại.
Bây giờ chúng ta vẫn sẽ có trong trí nhớ Jason.
Vì vậy, bây giờ chúng ta có thể gọi chuỗi được nối và chúng tôi nối với chuỗi com, vì
vậy bây giờ nó sẽ là Jason. com và sau đó chúng tôi in nó ra.
Và cuối cùng, nhưng không kém phần quan trọng, có lẽ là điều quan
trọng nhất của trang trình bày này, vì vậy chúng tôi không bị rò rỉ bộ nhớ mà chúng tôi gọi là miễn phí.
Luôn gọi miễn phí khi bạn gọi đến malloc.
Vì vậy, chúng ta hãy xem ví dụ này bên trong các khối mã.
Đây là ví dụ mã của chúng tôi bên trong
trình chỉnh sửa khối mã của chúng tôi.
Và điều đầu tiên bạn nên chú ý là chúng tôi đang
bao gồm tệp tiêu đề lib tiêu chuẩn vì đó là nơi chứa các hàm malloc và
các hàm realloc của chúng tôi cũng như chức năng miễn phí của chúng tôi.
Cũng bởi vì chúng tôi đang sử dụng một số hàm str, nối và sao
chép, chúng tôi đang bao gồm chuỗi. h.
Bây giờ ở dòng thứ tám, chúng ta sẽ tạo con trỏ ký tự của chúng ta.
Nó không có bộ nhớ được cấp phát cho nó.
Chúng ta nên khởi tạo cái này thành null vì
nó chưa trỏ đến bất cứ thứ gì. Ở dòng 11, chúng tôi gọi là malloc.
Và có lẽ chúng ta nên nói kích thước của char
gấp 15 lần trong trường hợp kích thước của byte
char khác nhau và sau đó chúng ta chuyển nó thành một
con trỏ ký tự
vì malloc trả về một khoảng trống. Sau đó chúng tôi sao chép nó.
Nếu chúng tôi cố gắng sao chép điều này và chúng tôi không thực hiện bất kỳ điều gì
trên dòng 11, chương trình sẽ bị sập vì chúng tôi không có bộ nhớ được cấp phát cho chuỗi trỏ đến.
Sau đó, chúng tôi chỉ cần in ra chuỗi và địa chỉ.
Bây giờ chúng ta gọi là realloc.
Chúng tôi cần lưu trữ nhiều dữ liệu hơn 15 byte,
vì vậy chúng tôi sẽ phân bổ lại
với 25 byte và chúng tôi có thể muốn làm lại sizeof char
để nhất quán.
Chúng tôi ép kiểu này và sau đó chúng tôi nối vào vị trí bộ nhớ
hiện có của chúng tôi có chứa jason. com, và chúng tôi sẽ in ra jason. com.
Và cuối cùng nhưng không kém phần quan trọng, ở dòng 20, chúng tôi giải phóng bộ nhớ
thực sự quan trọng.
Vì vậy, chúng ta hãy tiếp tục và chạy điều này. Và những gì bạn sẽ thấy là
khi chúng tôi in nó ra lần thứ hai, chúng tôi có sự ghép nối.
Vì vậy, chuỗi đầu
tiên của chúng tôi, chúng tôi đã cấp phát bộ nhớ và đó là một địa chỉ 000C2918.
Sau đó, chúng tôi tạo một địa chỉ mới bằng cách phân bổ lại và lấy kích thước hiện có của con trỏ mà
chúng tôi đã chuyển nó làm đối số.
Vì vậy, 000C0CD8 thực sự có nhiều dữ liệu hơn được
phân bổ cho nó, dữ liệu
hiện có trong jason và thêm 25 byte.
Và do đó, những gì bạn nhận thấy là các hoạt động nối.
Bởi vì khi chúng tôi phân
bổ lại, chúng tôi đặt nội dung jason vào bộ nhớ đó và chúng tôi chỉ mở rộng nó.
Vì vậy, rất nhiều lợi ích khi sử dụng các lệnh gọi malloc này, các cuộc gọi calloc và realloc miễn phí này.
Bạn muốn sử dụng chúng, bạn muốn hiểu chúng. Các chức năng sử dụng khá đơn giản.
Vì vậy, trong trang trình bày cuối cùng của chúng tôi, chúng ta hãy xem xét một số hướng dẫn.
Bạn muốn tránh phân bổ nhiều dung lượng bộ nhớ nhỏ, nó không hiệu quả.
Khi bạn phân bổ bộ nhớ trên
heap, nó có một số chi phí với nó.
Và nếu bạn phân bổ các khối bộ nhớ nhỏ, nó sẽ có chi phí cao hơn nhiều so với
việc phân bổ ít khối lớn hơn.
Vì vậy, hãy phân bổ bộ nhớ mà bạn
cần, nhưng đừng làm điều đó mỗi hai câu lệnh với phân bổ lại, hãy làm
những phần lớn.
Chỉ bám vào bộ nhớ chừng nào bạn cần. Bộ nhớ là một nguồn tài nguyên khan hiếm.
Khi nó ở trên đống, nó thậm chí còn khan hiếm hơn.
Vì vậy, khi bạn hoàn tất với một khối bộ nhớ, hãy gọi miễn phí.
Luôn đảm bảo rằng bạn cung cấp để giải phóng bộ nhớ mà bạn đã cấp phát, quyết định vị trí
trong mã của bạn, bạn sẽ giải phóng bộ nhớ khi bạn viết mã cấp phát bộ nhớ đó.
Đảm bảo rằng bạn có quyền truy cập vào con trỏ đó.
Nếu bạn cần làm cho con trỏ toàn cầu, thì bạn cần phải làm điều đó.
Nhưng thông thường bất cứ nơi nào bạn phân bổ trong chức năng đó, bạn nên giải phóng nó trong chức năng đó.
Nếu bạn có các chức năng khác giải phóng bộ
nhớ cho bạn, thì bạn đang cho rằng điều đó không tốt. Có quá nhiều khớp nối và phụ thuộc ở đó.
Người tạo ra nó phải là người xóa nó.
Đừng đặt trách nhiệm cho các chức năng khác và những thứ tương tự.
Đảm bảo rằng bạn không vô tình ghi đè địa chỉ bộ nhớ mà bạn đã cấp phát trên
heap trước khi giải phóng nó, điều này sẽ gây ra rò rỉ bộ nhớ.
Vì vậy, nếu bạn cố gắng ghi quá nhiều byte vào nó hoặc nếu bạn bị tràn, bạn có
thể gặp sự cố.
Vì vậy, hãy đặc biệt cẩn thận khi bạn cấp phát bộ nhớ trong một vòng
lặp vì điều này có thể gây ra sự cố tràn bộ đệm.
Tôi hy vọng nó sẽ có ích. Phân bổ bộ nhớ động là một vấn đề lớn.
Tôi sẽ đưa ra cho bạn một thử thách giúp bạn làm quen với điều này
hơn, nhưng hãy đảm bảo rằng bạn hiểu khái niệm này. Cảm ơn bạn.