std :: get_temporary_buffer가 필요한 이유는 무엇입니까?


84

어떤 용도로 사용해야 std::get_temporary_buffer합니까? Standard는 다음과 같이 말합니다.

최대 n 개의 인접한 T 개체를 저장하기에 충분한 저장소에 대한 포인터를 가져옵니다.

버퍼가 스택에 할당 될 것이라고 생각했지만 사실이 아닙니다. C ++ 표준에 따르면이 버퍼는 실제로 일시적인 것이 아닙니다. 이 함수는 ::operator new객체를 구성하지 않는 전역 함수에 비해 어떤 이점이 있습니다. 다음 진술이 동등하다는 것이 맞습니까?

int* x;
x = std::get_temporary_buffer<int>( 10 ).first;
x = static_cast<int*>( ::operator new( 10*sizeof(int) ) );

이 함수는 구문 설탕에만 존재합니까? 왜 temporary그 이름에 있습니까?


1996 년 7 월 1 일 Dr. Dobb의 저널에서 알고리즘 구현을위한 한 가지 사용 사례가 제안되었습니다 .

버퍼를 할당 할 수 없거나 요청 된 것보다 작 으면 알고리즘이 여전히 올바르게 작동하며 속도가 느려질뿐입니다.


2
참고 std::get_temporary_buffer로 C ++ 17에서는 더 이상 사용되지 않습니다.
Deqing

1
@Deqing 예. 또한 C ++ 20에서도 제거 될 것이며 아래에 언급 된 것과 같은 합당한 이유가 있습니다. 그래서 뷰어를 따라 이동 ..
니 코스

답변:


44

Stroustrup은 "The C ++ Programming Language" ( §19.4.4 , SE)에서 다음과 같이 말합니다 .

이 아이디어는 시스템이 빠른 할당에 대한 준비가 고정 된 크기 버퍼의 수를 유지할 수 있다는 것이다 그래서 공간을 요구하는 n 개의 객체가보다 더 많은 공간을 얻을 수 없음 . 그러나 더 적은 수익 get_temporary_buffer()을 낼 수도 있으므로 사용하는 한 가지 방법은 낙관적으로 많은 것을 요청한 다음 사용 가능한 것을 사용하는 것입니다.
[...] 때문에get_temporary_buffer() 은 저수준이고 임시 버퍼 관리에 최적화 될 가능성이 높기 장기 저장을 얻기 위해 new 또는 allocator :: allocate () 의 대안으로 사용해서는 안됩니다 .

또한 다음과 같이 두 가지 기능에 대한 소개를 시작합니다.

알고리즘이 제대로 작동하려면 종종 임시 공간이 필요합니다.

...하지만 일시적인 정의를 제공하지 않는 것 같습니다. 어디에서나 또는 장기적인 .

"수학에서 일반 프로그래밍으로"일화 에서는 Stepanov가 원래 STL 디자인에서 가짜 자리 표시 자 구현을 제공했다고 언급합니다.

놀랍게도 그는 STL 구현을 제공하는 모든 주요 공급 업체가 여전히이 끔찍한 구현을 사용하고 있다는 사실을 몇 년 후 발견했습니다. [...]


12
VC ++의 구현은 operator new할당이 성공할 때까지 연속적으로 더 작은 인수를 사용하여 호출하는 루프 인 것처럼 보입니다 . 특별한 최적화가 없습니다.
jalf

9
g ++ 4.5와 동일합니다. 의도 된 것 같지만 공급 업체에서 무시했습니다.
Georg Fritzsche

4
그들은 같은 소리라는 클래스에서이 기능을 포장해야crazy_allocator
0xbadf00d

하지만 진지하게 생각합시다-아마도 많은 스토리지를 할당하는 것이 좋을 것입니다. 이제 우리가 할 수있는 것은 시스템에 엄청난 양의 스토리지를 확보하도록 요청하는 것 get_temporary_buffer입니다. 그러나 요청한 금액보다 적은 금액을 받으면 (정말 안타깝게도) 보유하고있는 스토리지로 작업을 계속하려고합니다. bad_alloc사용 가능한 것보다 더 많은 메모리를 할당하려는 시도로 인해 발생하는 예외 를 포착하는 것보다 낫습니다 . 그러나 실제 유용성은 좋은 구현으로 서서 떨어집니다.
0xbadf00d 2014-06-21

@jalf C ++ 17에서 더 이상 사용되지 않습니다. :) ( cppreference.com 에 따라 ).
4LegsDrivenCat 2016-08-26

17

Microsoft의 표준 라이브러리 담당자는 다음과 같이 말합니다 ( 여기 ).

  • 'get_temporary_buffer'를 언제 사용해야하는지 설명해 주시겠습니까?

그것은 매우 특별한 목적을 가지고 있습니다. new (nothrow)와 같은 예외를 던지지는 않지만 new (nothrow)와 달리 객체를 생성하지 않습니다.

stable_partition ()과 같은 알고리즘에서 STL에 의해 내부적으로 사용됩니다. 이것은 N3126 25.3.13 [alg.partitions] / 11과 같은 마법의 단어가있을 때 발생합니다. stable_partition ()은 복잡도를 갖습니다. "최대 (마지막-처음) * 로그 (마지막-처음) 스왑이지만,있을 경우 선형 스왑 수만 충분한 추가 메모리입니다. " "추가 메모리가 충분한 경우"라는 마법의 단어가 나타나면 STL은 get_temporary_buffer ()를 사용하여 작업 공간을 확보하려고합니다. 가능하다면 알고리즘을보다 효율적으로 구현할 수 있습니다. 그렇게 할 수 없다면 시스템이 메모리 부족에 가깝게 실행 중이거나 관련 범위가 엄청 나기 때문에 알고리즘이 더 느린 기술로 되돌아 갈 수 있습니다.

STL 사용자의 99.9 %는 get_temporary_buffer ()에 대해 알 필요가 없습니다.


9

표준에 따르면 최대 n 요소에 . 즉, 예제는 5 개의 객체에 대해서만 충분히 큰 버퍼를 반환 할 수 있습니다.

이것에 대한 좋은 사용 사례를 상상하는 것은 꽤 어렵습니다. 메모리가 매우 제한된 플랫폼에서 작업하는 경우 "가능한 한 많은 메모리"를 얻는 편리한 방법 일 수 있습니다.

그러나 그러한 제한된 플랫폼에서는 가능한 한 메모리 할당자를 우회하고 메모리 풀이나 사용자가 완전히 제어 할 수있는 것을 사용한다고 생각합니다.


4

어떤 용도로 사용해야합니까? std::get_temporary_buffer?

이 함수 는 C ++ 17에서 더 이상 사용되지 않으므로 정답은 이제 "용도없이 사용하지 마십시오"입니다.


2
ptrdiff_t            request = 12
pair<int*,ptrdiff_t> p       = get_temporary_buffer<int>(request);
int*                 base    = p.first;
ptrdiff_t            respond = p.sencond;
assert( is_valid( base, base + respond ) );

응답요청 보다 적을 수 있습니다 .

size_t require = 12;
int*   base    = static_cast<int*>( ::operator new( require*sizeof(int) ) );
assert( is_valid( base, base + require ) );

base 의 실제 크기는 require 보다 크거나 같아야 합니다 .


2

아마도 (그냥 추측) 그것은 메모리 조각화와 관련이 있습니다. 시간 메모리를 계속 할당하고 할당 해제하지만 매번 임시 메모리를 할당 한 후 할당을 해제하기 전에 장기적으로 의도 한 메모리를 할당하면 힙이 조각난 상태가 될 수 있습니다.

따라서 get_temporary_buffer는 한 번 할당되는 필요한 것보다 더 큰 메모리 청크 (여러 요청을 수락 할 준비가 된 청크가 많을 수 있음)를 의도 할 수 있으며, 메모리가 필요할 때마다 덩어리. 따라서 메모리는 조각화되지 않습니다.


1
매우 흥미로운 생각입니다. 현재 대부분의 구현에서 작동 하는 그냥 할 수있는 일로 구현되는 것처럼 보이지만 , 이는 나머지 메모리 관리 루틴과 더 긴밀하게 지원되고 통합 될 수 있습니다. 실제로 이것이 적합 할 것으로 기대하고 있으며 Bjarnes의 의견도이를 암시하는 것 같습니다.
gustaf r

나는 지금 Bjarne이 그것에 대해 말하는 것을 보았고 그는 그것이 초기화없이 빠른 할당을 위해 설계되었다고 말했습니다. 따라서 할당 자 전용 (초기화 아님) void * operator new (size_t size)와 같지만 미리 할당되어 있으므로 할당하는 것이 더 빠릅니다.
Daniel Munoz
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.