จัดสรรหน่วยความจำ


11

คุณกำลังออกแบบภาษาการเขียนโปรแกรมลึกลับใหม่และคุณสมบัติหนึ่งที่คุณตัดสินใจเพิ่มคือตัวจัดสรรหน่วยความจำแบบไดนามิก ภาษาของคุณระบุพื้นที่ที่อยู่เสมือนพิเศษเฉพาะสำหรับพื้นที่โปรแกรมของผู้ใช้ สิ่งนี้แยกจากพื้นที่ที่อยู่ที่ใช้โดยตัวจัดสรรหน่วยความจำสำหรับสถานะภายในใด ๆ

เพื่อช่วยลดค่าใช้จ่ายในการกระจายการติดตั้งของคุณขนาดของรหัสจะต้องเล็กที่สุดเท่าที่จะทำได้

อินเตอร์เฟซ

คุณต้องจัดเตรียมสามฟังก์ชัน: การกำหนดค่าเริ่มต้นจัดสรรและยกเลิกการจัดสรร

การเริ่มต้น

Nฟังก์ชั่นนี้จะใช้เวลาพารามิเตอร์จำนวนเต็มบวกเดียว ซึ่งหมายความว่าโปรแกรมของผู้ใช้มีNไบต์ในพื้นที่ที่อยู่ซึ่งมีจำนวนN-1ไบต์ที่จะจัดสรรหน่วยความจำ ที่อยู่0นี้สงวนไว้สำหรับ "null"

มีการรับประกันว่าฟังก์ชั่นนี้จะถูกเรียกเพียงครั้งเดียวก่อนที่จะมีการจัดสรร / ยกเลิกการจัดสรร

โปรดทราบว่าฟังก์ชั่นนี้ไม่จำเป็นต้องจัดสรรหน่วยความจำกายภาพสำหรับพื้นที่ที่อยู่เสมือนของโปรแกรมผู้ใช้ โดยพื้นฐานแล้วคุณกำลังสร้าง "รูปลักษณ์และความรู้สึก" ของตัวจัดสรรหน่วยความจำแบบกลวง

จัดสรร

ฟังก์ชั่นการจัดสรรจะต้องทำการร้องขอจำนวนไบต์ของหน่วยความจำที่จะจัดสรร อินพุตรับประกันว่าจะเป็นบวก

ฟังก์ชั่นของคุณจะต้องส่งคืนที่อยู่จำนวนเต็มไปที่จุดเริ่มต้นของบล็อกที่จัดสรรหรือ0เพื่อแสดงว่าไม่มีบล็อกที่ต่อเนื่องกันของขนาดที่ร้องขอ หากบล็อกที่ต่อเนื่องกันของขนาดที่มีอยู่สามารถใช้ได้ทุกที่ในพื้นที่ที่อยู่คุณต้องจัดสรร!

คุณต้องตรวจสอบให้แน่ใจว่าไม่มีการจัดสรรสองบล็อกที่ทับซ้อนกัน

deallocate

ฟังก์ชั่นการจัดสรรคืนจะต้องใช้ที่อยู่ของการเริ่มต้นของบล็อกที่จัดสรรและอาจมีขนาดของบล็อกที่กำหนด

หน่วยความจำที่ถูกจัดสรรคืนจะพร้อมใช้งานอีกครั้งสำหรับการจัดสรร มันจะสันนิษฐานว่าที่อยู่ที่ป้อนเป็นที่อยู่ที่ถูกต้อง

ตัวอย่างการนำ Python มาใช้

โปรดทราบว่าคุณสามารถเลือกวิธีใดก็ได้ในการติดตามสถานะภายใน ในตัวอย่างนี้อินสแตนซ์ของชั้นติดตามของมัน

class myallocator:
    def __init__(self, N):
        # address 0 is special, it's always reserved for null
        # address N is technically outside the address space, so use that as a
        # marker
        self.addrs = [0, N]
        self.sizes = [1, 0]

    def allocate(self, size):
        for i,a1,s1,a2 in zip(range(len(self.addrs)),
                                 self.addrs[:-1], self.sizes[:-1],
                                 self.addrs[1:]):
            if(a2 - (a1+s1) >= size):
                # enough available space, take it
                self.addrs.insert(i+1, a1+s1)
                self.sizes.insert(i+1, size)
                return a1+s1
        # no contiguous spaces large enough to take our block
        return 0

    def deallocate(self, addr, size=0):
        # your implementation has the option of taking in a size parameter
        # in this implementation it's not used
        i = self.addrs.index(addr)
        del self.addrs[i]
        del self.sizes[i]

เกณฑ์การให้คะแนน

นี่คือรหัสกอล์ฟ รหัสที่สั้นที่สุดในหน่วยไบต์ชนะ คุณไม่จำเป็นต้องกังวลเกี่ยวกับหน่วยความจำไม่เพียงพอสำหรับสถานะภายในที่ต้องการโดยตัวจัดสรรของคุณ

ใช้รูมาตรฐานลูป

ลีดเดอร์บอร์ด


3
ฉันสงสัยว่ารายการ Python นั้นใช้หนึ่งไบต์ต่อองค์ประกอบ "หน่วยความจำที่จัดสรร" ต้องอยู่ในหน่วยไบต์หรือเป็น "ประเภททั่วไปประเภทรายการ / ภาษาของคุณ" หรือไม่?
Doorknob

4
ไม่จำเป็นต้องมีการจัดสรรจริง (ยกเว้นสิ่งที่คุณต้องการสำหรับการติดตามสถานะภายในซึ่งอยู่ในพื้นที่ที่อยู่เสมือนของตัวเอง) คุณแค่คืนค่าจำนวนเต็มกลับไปยังพื้นที่ที่อยู่เสมือนจริงที่มีขอบเขต จำกัด
helloworld922

To help reduce the cost of distributing your implementation the size of the code must be as small as possibleหรืออาจมีประสิทธิภาพ (ขนาดเล็กและมีประสิทธิภาพไม่เหมือนกัน) ที่สุด : D
The Coder


ในขณะที่ความท้าทายนี้ได้รับแรงบันดาลใจจากพื้นหลังการออกแบบภาษาการออกแบบภาษาไม่ได้เป็นส่วนหนึ่งของงาน (แทนที่จะใช้บางส่วน) จึงได้ลบแท็กออก
Martin Ender

คำตอบ:


4

ทับทิม, 80

i,a,d=->n{$m=?o*n},->n{$m.sub!(/\B#{?o*n}/,?f*n);"#$`".size},->n,s{$m[n,s]=?o*s}

เช่นเดียวกับคำตอบของ MegaTom แต่ใช้สตริงแทนอาร์เรย์เพื่อจัดเก็บสถานะ อักขระ "o" หมายถึงเซลล์เปิดในขณะที่ "f" หมายถึงเซลล์ที่เติม สิ่งนี้ช่วยให้เราใช้ฟังก์ชันการจัดการสตริง terse ของรูบี้:

?o*n เริ่มต้นสตริงของ n "o" s

/\B#{?o*n}/เป็นนิพจน์ทั่วไปที่ตรงกับ "o" s ต่อเนื่องซึ่งไม่รวมอักขระแรก sub!แทนที่คู่แรกด้วย n "f" s

"#$`" ให้สตริงทางด้านซ้ายของการจับคู่หรือสตริงว่างถ้าไม่มีการจับคู่ดังนั้นขนาดเป็นดัชนีที่จัดสรรหรือ 0

Deallocate เพียงตั้งค่าส่วนที่กำหนดของสตริงกลับไปที่ "o"


4

JavaScript (ES6), 88

การใช้ตัวแปรทั่วโลก_(กมากอาร์เรย์เบาบาง) ในการติดตาม

ตอนนี้ฉันจะทดสอบได้อย่างไร

I=n=>(_=[1],_[n]=0)
A=n=>_.some((x,i)=>i-p<n?(p=i+x,0):_[p]=n,p=1)?p:0
D=p=>delete _[p]

3

ทับทิม, 135

มีอาร์เรย์ส่วนกลางติดตามว่ามีการจัดสรรเซลล์แต่ละเซลล์หรือไม่

i=->n{$a=[!0]*n;$a[0]=0}
a=->n{s=$a.each_cons(n).to_a.index{|a|a.none?};n.times{|i|$a[s+i]=0}if s;s||0}
d=->s,n{n.times{|i|$a[s+i]=!0}}

1

Mathematica, 152

i=(n=#;l={{0,1},{#,#}};)&
a=If[#=={},0,l=l~Join~#;#[[1,1]]]&@Cases[l,{Except@n,e_}:>{e,e+#}/;Count[l,{a_,_}/;e<=a<e+#]<1,1,1]&
d=(l=l~DeleteCases~{#,_};)&

nเก็บขนาดรวมlเก็บสถานะภายใน ตัวจัดสรรจะพยายามจัดสรรด้านหลังส่วนอื่นของหน่วยความจำที่จัดสรร

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.