C ++에서 벡터의 초기 용량
이란 무엇입니까 capacity()
의 std::vector
기본 constructor에를 사용하여 생성되는가? 나는 그것이 size()
0 이라는 것을 압니다 . 기본 생성 벡터가 힙 메모리 할당을 호출하지 않는다고 말할 수 있습니까?
이렇게하면 .NET과 같은 단일 할당을 사용하여 임의 예약으로 배열을 만들 수 있습니다 std::vector<int> iv; iv.reserve(2345);
. 어떤 이유로 size()
2345 에서 시작하고 싶지 않다고 가정 해 봅시다 .
예 : Linux (g ++ 4.4.5, 커널 2.6.32 amd64)
#include <iostream>
#include <vector>
int main()
{
using namespace std;
cout << vector<int>().capacity() << "," << vector<int>(10).capacity() << endl;
return 0;
}
인쇄 0,10
. 규칙입니까, 아니면 STL 공급 업체에 따라 다릅니 까?
표준은 capacity
컨테이너 의 이니셜 을 지정하지 않으므로 구현에 의존하고 있습니다. 일반적인 구현은 용량을 0에서 시작하지만 보장 할 수는 없습니다. 반면에 당신의 전략을 더 잘 할 수있는 방법은 없습니다 std::vector<int> iv; iv.reserve(2345);
.
std :: vector의 저장소 구현은 크게 다르지만 제가 본 모든 것은 0부터 시작합니다.
다음 코드 :
#include <iostream>
#include <vector>
int main()
{
using namespace std;
vector<int> normal;
cout << normal.capacity() << endl;
for (unsigned int loop = 0; loop != 10; ++loop)
{
normal.push_back(1);
cout << normal.capacity() << endl;
}
std::cin.get();
return 0;
}
다음 출력을 제공합니다.
0
1
2
4
4
8
8
8
8
16
16
GCC 5.1 및 :
0
1
2
3
4
6
6
9
9
9
13
MSVC 2013에서.
표준을 이해하는 한 (실제로 참조 이름을 지정할 수는 없지만) 컨테이너 인스턴스화 및 메모리 할당은 합당한 이유로 의도적으로 분리되었습니다. 따라서 당신은
constructor
컨테이너 자체를 만들려면reserve()
to pre allocate a suitably large memory block to accomodate at least(!) a given number of objects
And this makes a lot of sense. The only right to exist for reserve()
is to give you the opportunity to code around possibly expensive reallocations when growing the vector. In order to be useful you have to know the number of objects to store or at least need to be able to make an educated guess. If this is not given you better stay away from reserve()
as you will just change reallocation for wasted memory.
So putting it all together:
- The standard intentionally does not specify a constructor that allows you to pre allocate a memory block for a specific number of objects (which would be at least more desirable than allocating an implementation specific, fixed "something" under the hood).
- Allocation shouldn't be implicit. So, to preallocate a block you need to make a separate call to
reserve()
and this need not be at the same place of construction (could/should of course be later, after you became aware of the required size to accomodate) - Thus if a vector would always preallocate a memory block of implementation defined size this would foil the intended job of
reserve()
, wouldn't it? - What would be the advantage of preallocating a block if the STL naturally cannot know the intended purpose and expected size of a vector? It'll be rather nonsensical, if not counter-productive.
- The proper solution instead is to allocate and implementation specific block with the first
push_back()
- if not already explicitely allocated before byreserve()
. - In case of a necessary reallocation the increase in block size is implementation specific as well. The vector implementations I know of start with an exponential increase in size but will cap the increment rate at a certain maximum to avoid wasting huge amounts of memory or even blowing it.
All this comes to full operation and advantage only if not disturbed by an allocating constructor. You have reasonable defaults for common scenarios that can be overriden on demand by reserve()
(and shrink_to_fit()
). So, even if the standard does not explicitely state so, I'm quite sure assuming that a newly constructed vector does not preallocate is a pretty safe bet for all current implementations.
As a slight addition to the other answers, I found that when running under debug conditions with Visual Studio a default constructed vector will still allocate on the heap even though the capacity starts at zero.
Specifically if _ITERATOR_DEBUG_LEVEL != 0 then vector will allocate some space to help with iterator checking.
https://docs.microsoft.com/en-gb/cpp/standard-library/iterator-debug-level
I just found this slightly annoying since I was using a custom allocator at the time and was not expecting the extra allocation.
Standard doesnt specify initial value for capacity but the STL container automatically grows to accomodate as much data as you put in, provided you don't exceed the maximum size(use max_size member function to know). For vector and string, growth is handled by realloc whenever more space is needed. Suppose you'd like to create a vector holding value 1-1000. Without using reserve, the code will typically result in between 2 and 18 reallocations during following loop:
vector<int> v;
for ( int i = 1; i <= 1000; i++) v.push_back(i);
Modifying the code to use reserve might result in 0 allocations during the loop:
vector<int> v;
v.reserve(1000);
for ( int i = 1; i <= 1000; i++) v.push_back(i);
Roughly to say, vector and string capacities grow by a factor of between 1.5 and 2 each time.
참고URL : https://stackoverflow.com/questions/12271017/initial-capacity-of-vector-in-c
'program tip' 카테고리의 다른 글
Global.asax에서 Application_Start와 Init를 언제 사용합니까? (0) | 2020.10.22 |
---|---|
MySQL 피벗 행을 동적 열 수로 (0) | 2020.10.22 |
Google Play-개발자 콘솔 통계가 업데이트되는 빈도 (0) | 2020.10.22 |
게시되지 않은 지역 상자를 사용하는 방법은 무엇입니까? (0) | 2020.10.22 |
도커 컨테이너가 종료되는 이유를 아는 방법은 무엇입니까? (0) | 2020.10.22 |