Các lượt nộp
    Danh sách bài
    Trang chủ
    Báo lỗi

    solution

    Đề bài: [Trình biên dịch] Bộ cấp phát ngăn xếp (arena allocator) với mark/release

    Trình biên dịch thường cấp phát vùng nhớ cho các khung ngăn xếp (stack frame) hoặc các cấu trúc tồn tại theo phạm vi (scope) bằng một bộ cấp phát ngăn xếp (stack/arena allocator): thay vì cấp phát/giải phóng từng khối riêng lẻ như malloc/free, bộ cấp phát chỉ giữ một con trỏ đỉnh (top pointer) và hỗ trợ giải phóng theo lô, theo thứ tự vào sau ra trước (LIFO) thông qua cơ chế đánh dấu (mark) và khôi phục (release) — rất phù hợp với việc vào/ra các khối lệnh lồng nhau khi biên dịch.

    Bộ nhớ arena có dung lượng cố định SSS byte, con trỏ đỉnh top ban đầu bằng 000. Có mmm lệnh thuộc ba loại:

    • ALLOC n: cấp phát nnn byte liên tiếp bắt đầu từ vị trí top hiện tại (nếu top + n <= S), sau đó tăng top thêm nnn; nếu không đủ chỗ (top + n > S) thì phép cấp phát thất bại và top không đổi.
    • MARK: lưu lại giá trị top hiện tại vào một ngăn xếp các điểm đánh dấu (để có thể khôi phục sau này).
    • RELEASE: lấy điểm đánh dấu được lưu gần nhất ra khỏi ngăn xếp và đặt lại top bằng giá trị đó (giải phóng tức thời toàn bộ những gì đã cấp phát kể từ MARK tương ứng).

    Dữ liệu đảm bảo mỗi lệnh RELEASE đều có một lệnh MARK tương ứng chưa được dùng trước đó (ngăn xếp mark không bao giờ rỗng khi gặp RELEASE).

    Ví dụ: S=20S=20S=20 và các lệnh ALLOC 5, MARK, ALLOC 8, ALLOC 10, RELEASE, ALLOC 4:

    • ALLOC 5: cấp tại địa chỉ 000, top=5.
    • MARK: lưu 555.
    • ALLOC 8: cấp tại địa chỉ 555, top=13.
    • ALLOC 10: cần 13+10=23>2013+10=23>2013+10=23>20 nên thất bại (in −1-1−1), top vẫn là 131313.
    • RELEASE: khôi phục top=5.
    • ALLOC 4: cấp tại địa chỉ 555, top=9. Đỉnh cao nhất (peak) từng đạt được trong suốt quá trình là 131313.
    • Định dạng đầu vào:

      Dòng đầu tiên gồm hai số nguyên SSS và mmm (0≤S≤1090 \le S \le 10^90≤S≤109, 0≤m≤20000 \le m \le 20000≤m≤2000) — dung lượng arena và số lệnh.

      mmm dòng tiếp theo, mỗi dòng là một lệnh: ALLOC n (0≤n≤1090 \le n \le 10^90≤n≤109), MARK, hoặc RELEASE.

    • Định dạng đầu ra:

      Với mỗi lệnh ALLOC n, in ra một dòng: địa chỉ bắt đầu (offset, đánh số từ 000) của khối vừa cấp nếu thành công, hoặc −1-1−1 nếu thất bại. Các lệnh MARK, RELEASE không in gì.

      Sau khi in xong kết quả của tất cả các lệnh ALLOC, in thêm 222 dòng:

      • Giá trị top (số byte đang được sử dụng) tại thời điểm kết thúc chương trình.
      • Giá trị peak — mức sử dụng bộ nhớ cao nhất (giá trị top lớn nhất) từng đạt được tại bất kỳ thời điểm nào trong suốt quá trình chạy.

    Ví dụ:

    Đầu vào:

    10 0
    

    Đầu ra:

    0
    0
    

    Đầu vào:

    20 6
    ALLOC 5
    MARK
    ALLOC 8
    ALLOC 10
    RELEASE
    ALLOC 4
    

    Đầu ra:

    0
    5
    -1
    5
    9
    13
    

    Đang tải editor...