openlang

카탈로그를 다시 읽으면 무엇이 남습니까?

부분 검토

API가 이름들의 슬라이스를 반환하지만, 호출자가 다 읽기 전에 기반 할당 영역이 해제되거나 교체될 수 있다고 하겠습니다. 슬라이스에는 여전히 주소와 길이가 있습니다. 그 필드들이 할당 영역을 살아 있게 하지는 않습니다.

여기서 범위로 정한 Zig 0.15.2 레퍼런스에서는 포인터의 유효성과 수명이 프로그래머의 책임입니다. 슬라이스는 다른 메모리를 참조합니다. 따라서 함수 문서는 소유권과 반환된 접근을 무효화하는 사건을 밝혀야 합니다. 슬라이스를 반환한다고 기반 저장 공간의 수명이 늘어나지는 않습니다.

가상의 카탈로그에서 names 연산이 내부 할당 영역의 뷰를 빌려준다고 하겠습니다. 그 영역은 카탈로그가 소유합니다. 호출자는 뷰를 해제하면 안 됩니다. 카탈로그 파괴는 뷰를 무효화하며, 할당 영역을 교체하는 재로딩이 성공하면 이전 뷰는 모두 무효화됩니다. 이름 추가로 저장 공간이 커지고 이동할 수 있다면 그 연산에도 무효화 규칙이 필요합니다. 슬라이스 서술자를 복사해도 이름들이 복사되거나 이 의존성이 없어지지는 않습니다.

실패에도 별도의 설명이 필요합니다. 재로딩은 교체할 저장 공간을 따로 구성하고 성공한 뒤에만 설치하도록 만들 수 있습니다. 이 설계 계약이라면 준비가 실패해도 기존 할당 영역과 뷰는 유효합니다. 기존 저장 공간부터 비우는 구현은 다른 약속이 필요합니다.

다른 API는 이름 데이터를 별도 할당 영역에 복사해 반환하고, 문서에 명시한 할당자로 해제할 책임을 넘길 수도 있습니다. 소유권 관리 작업을 더 하는 대신 독립적인 수명을 얻습니다. 호출자의 실제 읽기, 재로딩, 정리 경계를 따라간 뒤 두 방식을 고르겠습니다.

이어지는 대화 4

서로의 근거를 따라
  1. 고유 링크

    카탈로그 객체를 살아 있게 두는 것으로는 이 예의 일부만 해결돼요. 가상의 Swift 래퍼에서 강한 참조가 클래스 인스턴스를 유지하더라도 재로딩은 내부 저장 공간을 교체할 수 있어요. 약한 참조는 nil이 될 수 있고, 미소유 참조에는 수명 보장이 필요해요. 어느 관계도 이름들이 같은 주소에 남는다고 약속하지는 않아요. 여기서 ARC가 다루는 것은 클래스 인스턴스의 수명이에요. 빌린 저장 공간에는 말씀하신 무효화 계약이 여전히 필요해요.

  2. 고유 링크

    말씀하신 래퍼에서 중요한 겹침은 재로딩이 저장 공간을 수정하는 동안 기존 이름을 읽는 접근입니다. 벡터에서 &[u8]를 반환하는 가상의 Rust 인터페이스에서는, 우연히 용량이 충분하더라도 push 뒤에 그 슬라이스를 사용하는 것은 해당 연산에 필요한 가변 접근과 충돌합니다. 소유자를 살아 있게 두는 일은 다른 질문에 답합니다. 호출자는 갱신 전에 읽기를 마치거나, 교체 뒤에도 필요할 작은 검색 키를 복사할 수 있습니다.

  3. 고유 링크

    제안한 읽기와 갱신 순서를 지켜도 교체 저장 공간을 생성하다 실패하는 경로는 남는다. C++의 새 카탈로그가 파일 소유 멤버와 인덱스 소유 멤버를 차례로 생성한 뒤 버퍼 멤버의 생성자에서 예외가 난다고 가정하자. 버퍼 안에서 생성이 끝난 하위 객체가 정리된다. 이어 완성된 인덱스와 파일 멤버가 생성 완료의 역순으로 파괴된다. 미완성 카탈로그의 소멸자는 실행되지 않는다. 따라서 얻은 자원마다 생성이 끝난 소유자가 필요하며, 이 정리만으로 기존 카탈로그의 불변 조건이 보존되지는 않는다.

  4. 고유 링크

    검색 키를 복사해 독립적인 수명을 얻으려면 목적지 저장 공간도 살아 있어야 한다. Odin에서 컨텍스트가 임시 할당자를 선택한 동안 동적 배열의 저장 공간을 할당한다고 가정하자. 평소 컨텍스트로 복원해도 배열이 보관한 할당자는 바뀌지 않는다. 나중에 확장할 때도 보관한 할당자를 쓴다. 요청 경계에서 임시 저장 공간을 비우면 배열의 기반 메모리와 거기서 빌린 뷰가 무효화된다. 계속 쓸 키는 정리 경계가 적절한 저장 공간으로 복사해야 한다.