소유자와 함께 어레이를 할당하는 적절한 방법

바톱

기본 제어 블록의 종류와 함께 제네릭 유형의 배열을 동적으로 할당하려고합니다. 이것을이 "제어 블록"의 예시 코드로 취하십시오.

template<class T>
struct my_array{
    T* arr;
    unsigned size;
};

다중 할당을 피하기 위해 할당을 new한 번만 호출하려고합니다 . 이것은 내가 생각해 낸 코드입니다.

template<class T>
my_array<T> *alloc_new_array(unsigned size){
    unsigned align_mismatch = sizeof(my_array<T>) % alignof(my_array<T>);
    unsigned array_size = size * sizeof(T);
    unsigned struct_size = sizeof(my_array<T>) + align_mismatch ? 
        alignof(my_array<T>) - align_mismatch : 0; 

    char *memory = new char[array_size + struct_size];

    my_array<T> *arr = new (memory) my_array<T>;
    arr->arr = new (memory + struct_size) T[size];
    arr->size = size;
    return arr;
}

내가 염려하는 것은 :

  • 정확성-내가 구조체 패딩을 처리했다고 생각하지만 내가 놓친 것이있을 수 있습니다. 올바르게 계산했고 플랫폼에 관계없이 제대로 작동합니까?
  • 표준 준수-C ++ 규칙을 어 기고 UB를 발생시키지 않습니까? 나는 여기서 포인터 마법을하고 있다는 것을 알고 있으며 모든 것이 완전히 합법적인지 확실하지 않습니다.
맥심 에고 러쉬 킨

한 가지 예 :

#include <iostream>
#include <new>
#include <memory>
#include <numeric>

template<class T>
struct alignas(T) WithArray {
    unsigned const size_;

    static void* operator new(size_t size, unsigned elements) {
        return ::operator new(size + elements * sizeof(T));
    }

    static void operator delete(void* p, size_t /*size*/, unsigned /*elements*/) {
        return ::operator delete(p);
    }

    static void operator delete(void* p) {
        return ::operator delete(p);
    }

    T* get_elements() { return reinterpret_cast<T*>(this + 1); }

    T* begin() { return get_elements(); }
    T* end() { return get_elements() + size_; }

    WithArray(unsigned elements)
        : size_(elements)
    {
        std::uninitialized_default_construct_n(get_elements(), size_);
    }

    ~WithArray() {
        std::destroy_n(get_elements(), size_);
    }

    WithArray(WithArray const&) = delete;
    WithArray& operator=(WithArray const&) = delete;
};

int main() {
    unsigned elements = 10;
    std::unique_ptr<WithArray<int>> a(new (elements) WithArray<int>(elements));

    for(int& elem : *a)
        std::cout << elem << ' ';
    std::cout << '\n';

    std::iota(a->begin(), a->end(), 0);

    for(int& elem : *a)
        std::cout << elem << ' ';
    std::cout << '\n';
}

산출:

0 0 0 0 0 0 0 0 0 0 
0 1 2 3 4 5 6 7 8 9 

alignas(T)+ reinterpret_cast<T*>(this + 1)는 C99 유연한 배열 멤버의 C ++ 버전입니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

.cmake 파일의 소스와 함께 변수를 CMakeList.txt에 포함하는 적절한 방법

백그라운드에서 Promise와 함께 작동하는 EventEmitter를 만드는 적절한 방법

Flow와 함께 React Memo를 사용하는 적절한 방법은 무엇입니까?

PHP와 strcmp 함수를 사용하는 적절한 방법

파이프 BASH에서 어레이를 유지하는 적절한 방법

sf 객체와 함께 group_by () %> % summary () %> % mutate ()를 사용하는 적절한 절차

해당 값을 포함하는 행 수와 함께 테이블에서 고유한 값을 얻는 방법

ContentResolver와 함께 RecyclerView를 사용하여 전화의 모든 미디어를 검색하는 적절한 최신 방법은 무엇입니까?

미러링을 위해 두 개의 디스크와 함께 lvconvert를 사용하는 방법은 무엇입니까? -적절하지 않은 할당 가능한 범위

동적 데이터 소스(SQL)와 함께 자동 완성 각도 자료를 사용하는 방법

값을 포함하는 적절한 배열 요소를 계산하는 방법

'justifyContent'와 함께 요소를 찾는 '절대'를 수행하는 방법

선택적 include와 함께 where 절에서 연산자를 사용하는 방법은 무엇입니까?

할당 가능한 어레이를 포함하는 사용자 정의 Fortran 유형에 대한 OpenMP 감소

적절한 양의 메모리를 할당하는 방법(c)

동적 데이터와 함께 pdfMake를 사용하는 방법

Qt에서 할당하지 않고 (많은!) 숫자를 문자열로 변환하는 적절한 방법

고밀도 레이어와 함께 TensorFlow Dataset API를 사용하는 방법

불순한 함수와 함께 atomicModifyIORef를 사용하는 방법?

Micronaut와 함께 서비스 프로필을 사용하는 CLI 애플리케이션을 구현하는 적절한 방법

클라이언트가 Google Analytics와 함께 사용할 서버 인증 액세스 토큰을 얻는 적절한 방법

해당 사용자에 대한 많은 데이터와 함께 사용자와 함께 나열합니다. 일대다 테이블의 마지막 레코드를 각 사용자의 해당 목록에 추가하는 방법은 무엇입니까?

iOS9 HTTPS와 함께 작동하도록 AFNetworking 호출을 업데이트하는 적절한 방법은 무엇입니까 (오류 -1200, -9824)?

useEffect () 종속성과 함께 useNavigation () 후크를 사용하는 적절한 방법이 있습니까?

Codeception에서 수락 테스트와 함께 조명기를 사용하는 적절한 방법은 무엇입니까?

Go에서 http 처리기 내에서 pgx와 함께 컨텍스트를 사용하는 적절한 방법은 무엇입니까?

소리와 함께 경고 상자를 얻는 방법?

소비자를 종료하는 적절한 방법

작업자 스레드를 종료하는 적절한 방법