Re: Allocating vector of strings seem to crash. Allocating array of
strings seems to be ok .
On Dec 20, 6:56 pm, Rakesh Kumar <rakesh.use...@gmail.com> wrote:
On Dec 20, 8:17 am, "Victor Bazarov" <v.Abaza...@comAcast.net> wrote:
Rakesh Kumar wrote:
In a project of mine - I was trying to scale down the actual issue
to the following piece of code. I need to allocate an array of strings=
and reserve the individual string to a particular size (4K) .
I wrote 2 functions - allocVectorOfStrings() and
allocArrayOfStrings().
Each of them seem to allocate similar amounts of memory - but the
version of vectorOfStrings seem to crash with the following error -
"double free or corruption (out): 0x08055ff8 ***" .
I was just curious if I am doing anything fundamentally wrong here
to cause the issue.
#include <iostream>
#include <cstdlib>
#include <vector>
void allocVectorOfStrings();
void allocArrayOfStrings();
void allocVectorOfStrings() {
std::vector<std::string> * vt = new std::vector<std::string>();
vt->reserve(50);
'reserve' does not construct vector's elements. It only allocates
memory for constructing them later, when 'insert' is used. Here
'*vt' does not contain _any strings_. It's empty. It's _capable_
of containing at least 50 without reallocation of its storage. But
it doesn't have any elements.
for (size_t i = 0; i < vt->capacity(); ++i) {
This is a very bad idea. Never iterate to capacity. Always
iterate to size.
std::cout << "We are probably ok" << i << "\n";
No, you're not OK.
vt->operator[](i).reserve(40);
You're accessing a non-existent element at the index 'i' and
then calls a member functions for it. Undefined behaviour.
Still, a good implementation of the library will output a more
or less sensible error message when you do it. I get:
error: attempt to subscript container with out-of-bounds index 0,
but
container only holds 0 elements.
when I try it with g++, for example (provided I've activated
debugging, but I always do). And VC++ indicates "Expression:
vector subscript out of range" in its pop-up box. Rather clear
as well.
Thanks Victor.
The revised function seems to do what I intended in the first place.
void allocVectorOfStrings()
{
std::vector<std::string> vt(1024);
for (size_t i = 0; i < vt.size(); ++i)
{
std::cout << "Vector seems to be ok too" << i << "\n";
vt[i].reserve(4096);
}
}
Just a quick question - after a vector is allocated - is there
a way I can mass construct elements at one shot (instead of
using insert / push_back ) - similar to the construct shown
above.
In the above, the elements are mass constructed, in the
constructor of vt. In this case, they are copy constructed from
the default, std::string(), but you can pass any initial value
you want, and they will be copy constructed from that.
On the other hand, the capacity() is not part of the "value" of
a string, and is not necessarily copied by the copy constructor;
in order to ensure the capacity of all of the elements, I think
you do have to do something like the above. Alternatively, you
could do:
std::vector< std::string > vt(
1024,
std::string( 4096, '\0') ) ;
, which will ensure the actual size (and not just the capacity).
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34