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:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
|