메모리 할당 자


11

새로운 난해한 프로그래밍 언어를 설계하고 있으며 추가하기로 결정한 기능 중 하나는 동적 메모리 할당 자입니다. 귀하의 언어는 사용자의 프로그램 공간을위한 특별한 전용 가상 주소 공간을 지정합니다. 이것은 메모리 할당자가 내부 상태에 사용하는 주소 공간과 별개입니다.

구현 배포 비용을 줄이려면 코드 크기가 가능한 작아야합니다.

상호 작용

초기화, 할당 및 할당 해제의 세 가지 기능을 제공해야합니다.

초기화

이 함수는 단일 양의 정수 매개 변수를 사용 N합니다. 즉, 사용자 프로그램 N의 주소 공간 N-1에 메모리를 할당 할 바이트 가있는 바이트가 있습니다. 주소 0는 "널"로 예약되어 있습니다.

이 함수는 할당 / 할당 해제 호출 전에 정확히 한 번만 호출됩니다.

이 함수는 사용자 프로그램의 가상 주소 공간을위한 물리적 메모리를 할당 할 필요가 없습니다. 당신은 기본적으로 할로우 메모리 할당 자의 "모양과 느낌"을 만들고 있습니다.

할당

할당 함수는 할당 할 메모리 바이트 수를 요청해야합니다. 입력은 양수로 보장됩니다.

함수는 할당 된 블록의 시작 부분에 정수 주소를 반환하거나 0사용 가능한 요청 된 크기의 연속 블록이 없음을 나타내야합니다 . 사용 가능한 크기의 연속 블록이 주소 공간의 어느 곳에서나 사용 가능하면 할당해야합니다!

할당 된 두 블록이 겹치지 않도록해야합니다.

할당 해제

할당 해제 기능은 할당 된 블록의 시작 주소를 가져와야하며, 주어진 블록의 크기를 선택적으로 가질 수도 있습니다.

할당이 해제 된 메모리는 다시 할당 할 수 있습니다. 입력 주소가 유효한 주소라고 가정합니다.

파이썬 구현 예

내부 상태를 추적하는 방법을 선택할 수 있습니다. 이 예제에서 클래스 인스턴스는이를 추적합니다.

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
파이썬 목록이 요소 당 정확히 1 바이트를 차지한다고 의심합니다. "할당 된 메모리"는 바이트 단위 여야합니까, 아니면 "언어의 일반 배열 / 목록 유형"일 수 있습니까?
Doorknob

4
실제 할당이 필요하지 않습니다 (자체 가상 주소 공간에있는 내부 상태 추적을 위해 원하는 것을 제외하고). 추상 유한 가상 주소 공간으로 만 정수를 반환합니다.
helloworld922

To help reduce the cost of distributing your implementation the size of the code must be as small as possible아니면 가능한 한 효율적일 수 있습니까 (작고 효율적이지는 않습니까)? : D
코더


이 과제는 언어 디자인 배경과 관련이 있지만 언어 디자인은 실제로 작업의 일부가 아니므로 일부를 구현하는 것이 아니므로 태그를 제거했습니다.
Martin Ender 2019

답변:


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"문자는 채워진 셀을 나타냅니다. 이를 통해 Ruby의 비교적 간결한 문자열 조작 함수를 사용할 수 있습니다.

?o*n n "o"의 문자열을 초기화합니다.

/\B#{?o*n}/첫 문자를 포함하지 않는 n 개의 연속 "o"와 일치하는 정규식입니다. sub!첫 번째 일치 항목을 n "f"로 바꿉니다.

"#$`" 일치하는 왼쪽에 문자열을 제공하거나 일치하지 않는 경우 빈 문자열을 제공하므로 크기는 할당 된 인덱스 또는 0입니다.

할당 해제는 문자열의 지정된 섹션을 다시 "o"로 설정합니다.


4

자바 스크립트 (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

매스 매 티카, 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.