简体   繁体   中英

Can I create a C++ string/vector with specified length but no initialization?

I need create a string / vector . I know how long it should be, however, I'd like to write the right thing into it later. Can I create it with a specified length but without any initialization (neither explicit nor implicit), like what malloc does? Because I'll write into it properly before reading from it, it would be a waste of time to initialize it at construction.

I hoped I could write with arbitrary order after creating the vector, like

vector<int> v(10); // Some magic to create v with 10 of uninitialized ints
v[6] = 1;
v[3] = 2;
...

Seemingly that's impossible.

If I understand your question properly, you wantstd::vector::reserve or std::basic_string::reserve .

std::vector<int> v;               // empty vector
v.reserve(how_long_it_should_be); // insure the capacity
v.push_back(the_right_thing);     // add elements
...

Edit for question's edit

vector<int> v(10); , will always construct v with 10 default-initialized int , ie 0 . You might want std::array if you could know the size at compile time.

std::array<int, 10> v;  // construct v with 10 uninitialized int
v[6] = 1;
v[3] = 2;

LIVE

Using .reserve() on either containers will increase the .capacity() of the internal memory block allocated without calling any default constructors.

You can assert that the container has the right capacity at the moment you need it using .capacity() . Note that .size() will be different to .capacity() after a .reserve() as the first returns the number of actual objects inside the container, while the seconds returns the total number of objects the current memory block can handle without reallocation.

It is good practice (especially for std::vector ) to empirically .reserve() your containers to avoid extra allocations at runtime. If you are using at least C++11, in case you want the remaining memory back and you can deal with some copying/moving, you can use shrink_to_fit() .

Note that std::string::reserve differs from std::vector::reserve in case the new capacity requested is smaller than the current capacity. The string will take it as a non-binding request to shrink, while the vector will ignore the request.

Yes, you can, with boost::noinit_adaptor :

vector<int, boost::noinit_adaptor<std::allocator<int>> v(10);

Under the hood it redefines allocator::construct to do default initialization using new(p) T instead of value initialization new(p) T() .

For built-in types default initialization does nothing, whereas value initialization zero-initializes.

When growing a vector, the new object must be initialized one way or another. It's not possible to create a vector of uninitialized int objects, for example.

The closest you could get would be to define a class with a data member and a default constructor that does not initialize that member, eg:

struct bar { int x; bar() {} };

// ...
std::vector<bar> vec(5);

Then vec ultimately contains 5 uninitialized int subobjects.

The reserve function allocates memory but does not increase the count of objects in the vector; it does not help with the problem that when you do eventually want an object in the vector you must initialize that object.

Use .resize(x) to change the actual number of elements.
* If .size() > x then elements will be destroyed, back first.
* If .size() < x new elements will be added using their default constructor.

Use .reserve(x) to have the vector allocate memory for x elements but not instantiate any ( .size() will not change).
* If .size() < x no action will be taken, and the vector will be unaffected.

From C++11 you can use fill constructor: http://www.cplusplus.com/reference/vector/vector/vector/ (2) fill constructor Constructs a container with n elements. Each element is a copy of val (if provided). BTW: there is quite big difference between string and vector.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM