Làm thế nào để malloc () và free () hoạt động?


276

Tôi muốn biết làm thế nào mallocfreelàm việc.

int main() {
    unsigned char *p = (unsigned char*)malloc(4*sizeof(unsigned char));
    memset(p,0,4);
    strcpy((char*)p,"abcdabcd"); // **deliberately storing 8bytes**
    cout << p;
    free(p); // Obvious Crash, but I need how it works and why crash.
    cout << p;
    return 0;
}

Tôi sẽ thực sự biết ơn nếu câu trả lời sâu ở cấp độ bộ nhớ, nếu có thể.


5
Không nên thực sự phụ thuộc vào trình biên dịch và thư viện thời gian chạy được sử dụng?
Vilx-

9
điều đó sẽ phụ thuộc vào việc thực hiện CRT. Vì vậy, bạn không thể khái quát nó.
Naveen

58
mà strcpy ghi 9 byte, không phải 8. Đừng quên bộ kết thúc NULL ;-).
Evan Teran


2
@ LưuViênPhúc đó là C ++. Lưu ýcout <<
Braden hay nhất

Câu trả lời:


385

OK một số câu trả lời về malloc đã được đăng.

Phần thú vị hơn là cách thức hoạt động miễn phí (và theo hướng này, malloc cũng có thể được hiểu rõ hơn).

Trong nhiều triển khai malloc / miễn phí, miễn phí thường không trả lại bộ nhớ cho hệ điều hành (hoặc ít nhất là chỉ trong các trường hợp hiếm). Lý do là bạn sẽ có những khoảng trống trong heap của mình và do đó điều đó có thể xảy ra, rằng bạn chỉ cần kết thúc bộ nhớ ảo 2 hoặc 4 GB của mình bằng những khoảng trống. Điều này nên tránh, vì ngay khi bộ nhớ ảo kết thúc, bạn sẽ gặp rắc rối thực sự lớn. Lý do khác là, HĐH chỉ có thể xử lý các khối bộ nhớ có kích thước và căn chỉnh cụ thể. Cụ thể: Thông thường HĐH chỉ có thể xử lý các khối mà trình quản lý bộ nhớ ảo có thể xử lý (thường là bội số của 512 byte, ví dụ 4KB).

Vì vậy, trả lại 40 byte cho hệ điều hành sẽ không hoạt động. Vậy miễn phí làm gì?

Miễn phí sẽ đặt khối bộ nhớ trong danh sách khối miễn phí của riêng mình. Thông thường, nó cũng cố gắng kết hợp các khối liền kề với nhau trong không gian địa chỉ. Danh sách khối miễn phí chỉ là một danh sách vòng tròn của các khối bộ nhớ có một số dữ liệu quản trị ở đầu. Đây cũng là lý do tại sao việc quản lý các thành phần bộ nhớ rất nhỏ với malloc / free tiêu chuẩn không hiệu quả. Mỗi khối bộ nhớ cần dữ liệu bổ sung và với kích thước nhỏ hơn phân mảnh xảy ra nhiều hơn.

Danh sách miễn phí cũng là nơi đầu tiên mà malloc nhìn vào khi cần một đoạn bộ nhớ mới. Nó được quét trước khi nó gọi bộ nhớ mới từ HĐH. Khi một đoạn được tìm thấy lớn hơn bộ nhớ cần thiết, nó được chia thành hai phần. Một cái được trả lại cho người gọi, cái còn lại được đưa vào danh sách miễn phí.

Có nhiều tối ưu hóa khác nhau cho hành vi tiêu chuẩn này (ví dụ cho các đoạn bộ nhớ nhỏ). Nhưng vì malloc và miễn phí phải rất phổ biến, nên hành vi tiêu chuẩn luôn là dự phòng khi các lựa chọn thay thế không thể sử dụng được. Ngoài ra còn có tối ưu hóa trong việc xử lý danh sách miễn phí - ví dụ: lưu trữ các khối trong danh sách được sắp xếp theo kích thước. Nhưng tất cả các tối ưu hóa cũng có những hạn chế riêng của họ.

Tại sao mã của bạn bị sập:

Lý do là bằng cách viết 9 ký tự (đừng quên byte null theo dõi) vào một vùng có kích thước cho 4 ký tự, bạn có thể sẽ ghi đè lên dữ liệu quản trị được lưu trữ cho một đoạn bộ nhớ khác nằm trong "phía sau" khối dữ liệu của bạn ( vì dữ liệu này thường được lưu trữ "phía trước" các khối bộ nhớ). Khi rảnh thì cố gắng đưa đoạn của bạn vào danh sách miễn phí, nó có thể chạm vào dữ liệu quản trị này và do đó vấp phải một con trỏ bị ghi đè. Điều này sẽ sụp đổ hệ thống.

Đây là một hành vi khá duyên dáng. Tôi cũng đã thấy các tình huống trong đó một con trỏ chạy trốn ở đâu đó đã ghi đè lên dữ liệu trong danh sách không có bộ nhớ và hệ thống không gặp sự cố ngay lập tức nhưng một số chương trình con sau đó. Ngay cả trong một hệ thống phức tạp trung bình, các vấn đề như vậy có thể thực sự, rất khó để gỡ lỗi! Trong một trường hợp tôi đã tham gia, chúng tôi (một nhóm các nhà phát triển lớn hơn) phải mất vài ngày để tìm ra lý do của sự cố - vì nó nằm ở một vị trí hoàn toàn khác với vị trí được chỉ ra bởi kết xuất bộ nhớ. Nó giống như một quả bom hẹn giờ. Bạn biết đấy, "miễn phí" hoặc "malloc" tiếp theo của bạn sẽ gặp sự cố, nhưng bạn không biết tại sao!

Đó là một số vấn đề tồi tệ nhất của C / C ++ và một lý do tại sao con trỏ có thể gây ra vấn đề như vậy.


62
Vì vậy, nhiều người không nhận ra rằng free () có thể không trả lại bộ nhớ cho HĐH, điều đó thật đáng giận. Cảm ơn đã giúp soi sáng cho họ.
Artelius

Artelius: trái lại, mới sẽ luôn luôn như vậy?
Guillaume07

3
@ Guillaume07 Tôi giả sử bạn có nghĩa là xóa, không phải mới. Không, nó không (nhất thiết). xóa và miễn phí làm (gần) điều tương tự. Đây là mã mỗi người gọi trong MSVC2013: goo.gl/3O2Kyu
Yay295 22/03/2015

1
xóa sẽ luôn gọi hàm hủy, nhưng bộ nhớ có thể đi vào danh sách miễn phí để cấp phát sau. Tùy thuộc vào việc triển khai, nó thậm chí có thể là cùng một danh sách miễn phí mà malloc sử dụng.
David C.

1
@Juergen Nhưng khi free () đọc thêm byte chứa thông tin có bao nhiêu bộ nhớ được phân bổ từ malloc, nó sẽ nhận được 4. Sau đó, sự cố đã xảy ra như thế nào hoặc làm thế nào () chạm vào dữ liệu quản trị?
Hành vi không xác định

56

Như aluser nói trong chủ đề diễn đàn này :

Quá trình của bạn có một vùng bộ nhớ, từ địa chỉ x đến địa chỉ y, được gọi là heap. Tất cả dữ liệu malloc'd của bạn sống trong khu vực này. malloc () giữ một số cấu trúc dữ liệu, giả sử một danh sách, của tất cả các khối không gian miễn phí trong heap. Khi bạn gọi malloc, nó sẽ xem qua danh sách một đoạn đủ lớn cho bạn, trả về một con trỏ cho nó và ghi lại thực tế rằng nó không còn miễn phí nữa cũng như nó lớn như thế nào. Khi bạn gọi free () với cùng một con trỏ, free () sẽ tìm ra khối đó lớn như thế nào và thêm nó trở lại vào danh sách các khối miễn phí (). Nếu bạn gọi malloc () và nó không thể tìm thấy bất kỳ khối nào đủ lớn trong heap, nó sử dụng tòa nhà brk () để phát triển đống, tức là tăng địa chỉ y và gây ra tất cả các địa chỉ giữa y cũ và y mới là bộ nhớ hợp lệ. brk () phải là một tòa nhà cao tầng;

malloc () phụ thuộc vào hệ thống / trình biên dịch nên thật khó để đưa ra câu trả lời cụ thể. Tuy nhiên, về cơ bản, nó sẽ theo dõi bộ nhớ được phân bổ và tùy thuộc vào cách thức thực hiện để các cuộc gọi miễn phí của bạn có thể thất bại hoặc thành công.

malloc() and free() don't work the same way on every O/S.


1
Đó là lý do tại sao nó được gọi là hành vi không xác định. Một thực hiện có thể làm cho quỷ bay ra khỏi mũi của bạn khi bạn gọi miễn phí sau khi viết không hợp lệ. Bạn không bao giờ biết.
Braden hay nhất

35

Một triển khai của malloc / miễn phí thực hiện như sau:

  1. Nhận một khối bộ nhớ từ HĐH thông qua sbrk () (cuộc gọi Unix).
  2. Tạo một tiêu đề và chân trang xung quanh khối bộ nhớ đó với một số thông tin như kích thước, quyền và vị trí của khối tiếp theo và trước đó.
  3. Khi có cuộc gọi đến malloc, một danh sách được tham chiếu tới các khối có kích thước phù hợp.
  4. Khối này sau đó được trả lại và các tiêu đề và chân trang được cập nhật tương ứng.

25

Bảo vệ bộ nhớ có độ chi tiết của trang và sẽ yêu cầu tương tác kernel

Mã ví dụ của bạn về cơ bản hỏi tại sao chương trình ví dụ không mắc bẫy và câu trả lời là bảo vệ bộ nhớ là một tính năng hạt nhân và chỉ áp dụng cho toàn bộ trang, trong khi bộ cấp phát bộ nhớ là một tính năng của thư viện và nó quản lý .. mà không cần thực thi .. tùy ý .. khối có kích thước thường nhỏ hơn nhiều so với các trang.

Bộ nhớ chỉ có thể được xóa khỏi chương trình của bạn theo đơn vị trang và thậm chí điều đó khó có thể được quan sát.

calloc (3) và malloc (3) tương tác với kernel để lấy bộ nhớ, nếu cần. Nhưng hầu hết các triển khai miễn phí (3) không trả lại bộ nhớ cho kernel 1 , họ chỉ cần thêm nó vào danh sách miễn phí mà calloc () và malloc () sẽ tham khảo sau để sử dụng lại các khối đã phát hành.

Ngay cả khi một () muốn trả lại bộ nhớ cho hệ thống, nó sẽ cần ít nhất một trang bộ nhớ liền kề để có được hạt nhân thực sự bảo vệ vùng, do đó, việc phát hành một khối nhỏ sẽ chỉ dẫn đến thay đổi bảo vệ nếu nó là các cuối cùng khối nhỏ trong một trang.

Vì vậy, khối của bạn là ở đó, ngồi trong danh sách miễn phí. Bạn hầu như luôn có thể truy cập nó và bộ nhớ gần như thể nó vẫn được phân bổ. C biên dịch thẳng vào mã máy và không có các sắp xếp gỡ lỗi đặc biệt, không có kiểm tra độ tỉnh táo trên các tải và cửa hàng. Bây giờ, nếu bạn thử và truy cập một khối miễn phí, hành vi không được xác định theo tiêu chuẩn để không đưa ra yêu cầu vô lý đối với người thực hiện thư viện. Nếu bạn thử và truy cập bộ nhớ đã giải phóng hoặc meory bên ngoài một khối được phân bổ, có nhiều thứ có thể sai:

  • Đôi khi các bộ cấp phát duy trì các khối bộ nhớ riêng biệt, đôi khi chúng sử dụng một tiêu đề mà chúng phân bổ ngay trước hoặc sau ("chân trang", tôi đoán) khối của bạn, nhưng chúng chỉ muốn sử dụng bộ nhớ trong khối cho mục đích giữ danh sách miễn phí kết nối với nhau. Nếu vậy, việc đọc khối của bạn vẫn ổn, nhưng nội dung của nó có thể thay đổi và việc ghi vào khối có thể sẽ khiến bộ cấp phát hoạt động sai hoặc gặp sự cố.
  • Đương nhiên, khối của bạn có thể được phân bổ trong tương lai, và sau đó nó có thể bị ghi đè bởi mã của bạn hoặc một thói quen của thư viện hoặc với số 0 bởi calloc ().
  • Nếu khối được phân bổ lại, nó cũng có thể thay đổi kích thước của nó, trong trường hợp đó, nhiều liên kết hoặc khởi tạo sẽ được viết ở nhiều nơi hơn.
  • Rõ ràng là bạn có thể tham chiếu quá xa phạm vi mà bạn vượt qua một ranh giới của một trong những phân đoạn được biết đến của chương trình của bạn và trong trường hợp này bạn sẽ mắc bẫy.

Nguyên lý hoạt động

Vì vậy, làm việc ngược từ ví dụ của bạn với lý thuyết tổng thể, malloc (3) lấy bộ nhớ từ kernel khi nó cần và thường là theo đơn vị trang. Các trang này được chia hoặc hợp nhất theo yêu cầu của chương trình. Malloc và hợp tác miễn phí để duy trì một thư mục. Họ kết hợp các khối miễn phí liền kề khi có thể để có thể cung cấp các khối lớn. Thư mục có thể có hoặc không liên quan đến việc sử dụng bộ nhớ trong các khối được giải phóng để tạo thành một danh sách được liên kết. . chương trình.


1. Thực tế là rất ít việc triển khai free () cố gắng trả lại bộ nhớ cho hệ thống không nhất thiết là do các trình triển khai bị tắt. Tương tác với kernel chậm hơn nhiều so với việc thực thi mã thư viện và lợi ích sẽ nhỏ. Hầu hết các chương trình có dung lượng bộ nhớ ổn định hoặc tăng, do đó, thời gian để phân tích heap tìm kiếm bộ nhớ có thể trả lại sẽ hoàn toàn lãng phí. Các lý do khác bao gồm thực tế là sự phân mảnh bên trong làm cho các khối liên kết trang không thể tồn tại và có khả năng việc trả lại một khối sẽ phân chia các khối sang hai bên. Cuối cùng, một vài chương trình trả lại số lượng lớn bộ nhớ có khả năng bỏ qua malloc () và chỉ đơn giản là phân bổ và các trang miễn phí.


Câu trả lời tốt. Xin giới thiệu bài viết: Phân bổ lưu trữ động: Một khảo sát và đánh giá quan trọng của Wilson và cộng sự để đánh giá chuyên sâu về các cơ chế nội bộ, như trường tiêu đề và danh sách miễn phí, được sử dụng bởi các nhà phân bổ.
Thủ môn444

23

Về lý thuyết, malloc lấy bộ nhớ từ hệ điều hành cho ứng dụng này. Tuy nhiên, vì bạn có thể chỉ muốn 4 byte và HĐH cần hoạt động trong các trang (thường là 4k), malloc còn làm được nhiều hơn thế. Nó lấy một trang và đặt thông tin của chính nó vào đó để nó có thể theo dõi những gì bạn đã phân bổ và giải phóng khỏi trang đó.

Khi bạn phân bổ 4 byte, ví dụ, malloc cung cấp cho bạn một con trỏ tới 4 byte. Điều bạn có thể không nhận ra là bộ nhớ 8-12 byte trước 4 byte của bạn đang được malloc sử dụng để tạo chuỗi tất cả bộ nhớ bạn đã phân bổ. Khi bạn gọi miễn phí, nó sẽ đưa con trỏ của bạn, sao lưu vào vị trí của dữ liệu và hoạt động trên đó.

Khi bạn giải phóng bộ nhớ, malloc sẽ loại bỏ bộ nhớ đó khỏi chuỗi ... và có thể hoặc không thể trả lại bộ nhớ đó cho hệ điều hành. Nếu không, việc truy cập bộ nhớ đó có thể sẽ thất bại, vì HĐH sẽ lấy đi quyền của bạn để truy cập vị trí đó. Nếu malloc giữ bộ nhớ (vì nó có những thứ khác được phân bổ trong trang đó hoặc để tối ưu hóa), thì truy cập sẽ hoạt động. Nó vẫn sai, nhưng nó có thể hoạt động.

TUYÊN BỐ TỪ CHỐI: Những gì tôi mô tả là một triển khai phổ biến của malloc, nhưng không có nghĩa là cách duy nhất có thể.


12

Dòng strcpy của bạn cố lưu trữ 9 byte, chứ không phải 8, vì bộ kết thúc NUL. Nó gọi hành vi không xác định.

Cuộc gọi miễn phí có thể hoặc không thể bị sập. Bộ nhớ "sau" 4 byte phân bổ của bạn có thể được sử dụng cho mục đích khác khi triển khai C hoặc C ++ của bạn. Nếu nó được sử dụng cho mục đích khác, thì việc viết nguệch ngoạc khắp nơi sẽ khiến "cái gì đó khác" bị sai, nhưng nếu nó không được sử dụng cho bất cứ điều gì khác, thì bạn có thể thoát khỏi nó. "Tránh xa nó" nghe có vẻ tốt, nhưng thực sự tệ, vì điều đó có nghĩa là mã của bạn sẽ xuất hiện để chạy OK, nhưng trong tương lai, bạn có thể không thoát khỏi nó.

Với bộ cấp phát bộ nhớ kiểu gỡ lỗi, bạn có thể thấy rằng giá trị bảo vệ đặc biệt đã được ghi ở đó và kiểm tra miễn phí cho giá trị đó và hoảng loạn nếu không tìm thấy.

Mặt khác, bạn có thể thấy rằng 5 byte tiếp theo bao gồm một phần của nút liên kết thuộc về một số bộ nhớ khác chưa được phân bổ. Giải phóng khối của bạn cũng có thể liên quan đến việc thêm nó vào danh sách các khối có sẵn và vì bạn đã viết nguệch ngoạc trong nút danh sách, thao tác đó có thể hủy bỏ một con trỏ có giá trị không hợp lệ, gây ra sự cố.

Tất cả phụ thuộc vào bộ cấp phát bộ nhớ - việc triển khai khác nhau sử dụng các cơ chế khác nhau.


12

Cách malloc () và free () hoạt động phụ thuộc vào thư viện thời gian chạy được sử dụng. Nói chung, malloc () phân bổ một đống (một khối bộ nhớ) từ hệ điều hành. Mỗi yêu cầu tới malloc () sau đó phân bổ một đoạn nhỏ của bộ nhớ này sẽ trả về một con trỏ cho người gọi. Các thói quen cấp phát bộ nhớ sẽ phải lưu trữ một số thông tin bổ sung về khối bộ nhớ được phân bổ để có thể theo dõi bộ nhớ đã sử dụng và bộ nhớ trống trên heap. Thông tin này thường được lưu trữ trong một vài byte ngay trước khi con trỏ được trả về bởi malloc () và nó có thể là một danh sách các khối bộ nhớ được liên kết.

Bằng cách viết qua khối bộ nhớ được cấp phát bởi malloc () rất có thể bạn sẽ phá hủy một số thông tin lưu giữ sách của khối tiếp theo có thể là khối bộ nhớ chưa sử dụng còn lại.

Một nơi mà chương trình của bạn cũng có thể gặp sự cố là khi sao chép quá nhiều ký tự vào bộ đệm. Nếu các ký tự phụ được đặt bên ngoài heap, bạn có thể bị vi phạm quyền truy cập khi bạn đang cố ghi vào bộ nhớ không tồn tại.


6

Điều này không có gì đặc biệt để làm với malloc và miễn phí. Chương trình của bạn thể hiện hành vi không xác định sau khi bạn sao chép chuỗi - nó có thể bị sập tại thời điểm đó hoặc tại bất kỳ thời điểm nào sau đó. Điều này sẽ đúng ngay cả khi bạn không bao giờ sử dụng malloc và miễn phí, và phân bổ mảng char trên ngăn xếp hoặc tĩnh.


5

malloc và miễn phí là phụ thuộc thực hiện. Một triển khai điển hình liên quan đến việc phân vùng bộ nhớ khả dụng thành một "danh sách miễn phí" - một danh sách được liên kết của các khối bộ nhớ khả dụng. Nhiều triển khai nhân tạo chia nó thành các đối tượng nhỏ so với lớn. Các khối miễn phí bắt đầu với thông tin về khối bộ nhớ lớn như thế nào và vị trí của khối tiếp theo, v.v.

Khi bạn malloc, một khối được kéo từ danh sách miễn phí. Khi bạn rảnh, khối được đưa trở lại trong danh sách miễn phí. Rất có thể, khi bạn ghi đè lên cuối con trỏ, bạn đang viết trên tiêu đề của một khối trong danh sách miễn phí. Khi bạn giải phóng bộ nhớ, free () cố gắng nhìn vào khối tiếp theo và có thể cuối cùng nhấn một con trỏ gây ra lỗi bus.


4

Vâng, nó phụ thuộc vào việc thực hiện cấp phát bộ nhớ và hệ điều hành.

Trong các cửa sổ, ví dụ, một quá trình có thể yêu cầu một trang hoặc nhiều RAM hơn. Hệ điều hành sau đó gán các trang đó cho quá trình. Tuy nhiên, đây không phải là bộ nhớ được phân bổ cho ứng dụng của bạn. Bộ cấp phát bộ nhớ CRT sẽ đánh dấu bộ nhớ là một khối "có sẵn" liền kề. Bộ cấp phát bộ nhớ CRT sau đó sẽ chạy qua danh sách các khối miễn phí và tìm khối nhỏ nhất có thể mà nó có thể sử dụng. Sau đó, nó sẽ lấy bao nhiêu khối mà nó cần và thêm nó vào danh sách "được phân bổ". Kèm theo phần đầu của phân bổ bộ nhớ thực tế sẽ là một tiêu đề. Tiêu đề này sẽ chứa nhiều thông tin khác nhau (ví dụ, nó có thể chứa các khối được phân bổ tiếp theo và trước đó để tạo thành một danh sách được liên kết. Rất có thể nó sẽ chứa kích thước của phân bổ).

Free sau đó sẽ xóa tiêu đề và thêm nó trở lại danh sách bộ nhớ miễn phí. Nếu nó tạo thành một khối lớn hơn với các khối tự do xung quanh, các khối này sẽ được thêm vào với nhau để tạo ra một khối lớn hơn. Nếu toàn bộ một trang hiện đang miễn phí, rất có thể, người cấp phát sẽ trả lại trang cho HĐH.

Nó không phải là một vấn đề đơn giản. Phần phân bổ hệ điều hành hoàn toàn nằm ngoài tầm kiểm soát của bạn. Tôi khuyên bạn nên đọc qua một cái gì đó như Doug Lea's Malloc (DLMalloc) để hiểu về cách phân bổ khá nhanh sẽ hoạt động.

Chỉnh sửa: Sự cố của bạn sẽ được gây ra bởi thực tế là bằng cách viết lớn hơn phân bổ bạn đã ghi đè lên tiêu đề bộ nhớ tiếp theo. Cách này khi giải phóng nó sẽ rất bối rối về việc chính xác nó là gì và làm thế nào để hợp nhất vào khối sau. Điều này có thể không luôn luôn gây ra sự cố ngay lập tức trên miễn phí. Nó có thể gây ra một vụ tai nạn sau này. Nói chung tránh ký ức ghi đè!


3

Chương trình của bạn gặp sự cố vì nó sử dụng bộ nhớ không thuộc về bạn. Nó có thể được sử dụng bởi người khác hoặc không - nếu bạn may mắn gặp sự cố, nếu không vấn đề có thể bị ẩn trong một thời gian dài và quay lại và cắn bạn sau đó.

Theo như malloc / triển khai miễn phí - toàn bộ sách được dành cho chủ đề. Về cơ bản, bộ cấp phát sẽ nhận được bộ nhớ lớn hơn từ HĐH và quản lý chúng cho bạn. Một số vấn đề mà người cấp phát phải giải quyết là:

  • Làm thế nào để có được bộ nhớ mới
  • Cách lưu trữ - (danh sách hoặc cấu trúc khác, nhiều danh sách cho các khối bộ nhớ có kích thước khác nhau, v.v.)
  • Phải làm gì nếu người dùng yêu cầu nhiều bộ nhớ hơn hiện có (yêu cầu thêm bộ nhớ từ HĐH, tham gia một số khối hiện có, cách tham gia chính xác, ...)
  • Phải làm gì khi người dùng giải phóng bộ nhớ
  • Bộ cấp phát gỡ lỗi có thể cung cấp cho bạn khối lớn hơn mà bạn yêu cầu và điền vào mẫu byte đó, khi bạn giải phóng bộ nhớ, bộ cấp phát có thể kiểm tra xem có được ghi bên ngoài khối không (có thể xảy ra trong trường hợp của bạn) ...

2

Thật khó để nói vì hành vi thực tế là khác nhau giữa các trình biên dịch / thời gian chạy khác nhau. Ngay cả các bản dựng gỡ lỗi / phát hành có hành vi khác nhau. Các bản dựng gỡ lỗi của VS2005 sẽ chèn các điểm đánh dấu giữa các cấp phát để phát hiện lỗi bộ nhớ, vì vậy thay vì sự cố, nó sẽ khẳng định trong free ().


1

Điều quan trọng nữa là nhận ra rằng chỉ cần di chuyển con trỏ ngắt chương trình xung quanh brksbrkkhông thực sự phân bổ bộ nhớ, nó chỉ thiết lập không gian địa chỉ. Ví dụ, trên Linux, bộ nhớ sẽ được "sao lưu" bởi các trang vật lý thực tế khi phạm vi địa chỉ đó được truy cập, điều này sẽ dẫn đến lỗi trang và cuối cùng sẽ dẫn đến việc gọi kernel vào bộ cấp phát trang để lấy trang sao lưu.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.