Environment:
Memory Limit: 512 MB
Run the following code, will finish smoothly:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
using namespace std;
int main() {
long long N;
vector<long long> set3;
for(long long i = 1; i < 20000000; ++i) {
set3.push_back(i);
}
cout << "count:" << set3.size() << " capacity:" << set3.capacity() << endl;
vector<long long> set5;
for(long long i = 1; i < 12000000; ++i) {
set5.push_back(i);
}
cout << "count:" << set5.size() << " capacity:" << set5.capacity() << endl;
return 0;
}
If I swap set3 and set5, it will fail by exception:
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Here is the failed code:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
using namespace std;
int main() {
long long N;
vector<long long> set5;
for(long long i = 1; i < 12000000; ++i) {
set5.push_back(i);
}
cout << "count:" << set5.size() << " capacity:" << set5.capacity() << endl;
vector<long long> set3;
for(long long i = 1; i < 20000000; ++i) {
set3.push_back(i);
}
cout << "count:" << set3.size() << " capacity:" << set3.capacity() << endl;
return 0;
}
Why?
Here is another successful case, we can even succeeded in allocating 370 MB by vector::assign
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
using namespace std;
int main() {
long long N;
vector<long long> set5;
for(long long i = 1; i < 12000000; ++i) {
set5.push_back(i);
}
cout << "count:" << set5.size() << " capacity:" << set5.capacity() << endl;
vector<long long> set3;
//set3.assign(49807360, 0); // fail: 49807360 * 64 / 8 / 1024 / 1024 == 380 MB
set3.assign(48496640, 0); // succeed: 48496640 * 64 / 8 / 1024 / 1024 == 370 MB
/*
for(long long i = 1; i < 20000000; ++i) {
set3.push_back(i);
}
*/
cout << "count:" << set3.size() << " capacity:" << set3.capacity() << endl;
return 0;
}
Why does memory allocation by vector's push_back (causing memory increase from 128MB to 256MB) fail on 384 MB; while vector.assign(370MB, much bigger than 256 MB) on the same 384 MB will succeed?
Is this a memory fragmentation issue?
In the successful case:
Allocate for set3: (by vector::push_back)
256 MB out of 512 MB ---- Good;
then allocate for set5: (by vector::push_back)
128 MB out of the remaining 256 MB ---- Good;
In the failed case:
Allocate for set5: (by vector::push_back)
128 MB out of 512 MB ---- Good;
then allocate for set3: (by vector::push_back)
256 MB out of the remaining 384 MB ---- Fail.
In another successful case:
Allocate for set5: (by vector::push_back)
128 MB out of 512 MB ---- Good;
then allocate for set3: (by vector::assign)
370 MB out of the remaining 384 MB ---- Good.