By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,959 Members | 1,196 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,959 IT Pros & Developers. It's quick & easy.

Allocating vector of strings seem to crash. Allocating array ofstrings seems to be ok .

P: n/a
Hi All -
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);
for (size_t i = 0; i < vt->capacity(); ++i) {
std::cout << "We are probably ok" << i << "\n";
vt->operator[](i).reserve(40);
}
delete vt;
}

void allocArrayOfStrings() {
std::string * vt = new std::string[4096];
for (size_t i = 0; i < 1024; ++i) {
std::cout << "We are probably ok" << i << "\n";
vt[i].reserve(4096);
}
delete [] vt;
}

int main()
{
allocArrayOfStrings();
allocVectorOfStrings(); //This function crashes
return EXIT_SUCCESS;
}
Dec 20 '07 #1
Share this Question
Share on Google+
4 Replies


P: n/a
Rakesh Kumar wrote:
Hi All -
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.
}
delete vt;
}

void allocArrayOfStrings() {
std::string * vt = new std::string[4096];
Here 'vt' contains all 4096 elements.
for (size_t i = 0; i < 1024; ++i) {
std::cout << "We are probably ok" << i << "\n";
Yes, you are.
vt[i].reserve(4096);
'vt[i]' represents a real string. You can call 'reserve' for
it, no problem.
}
delete [] vt;
}

int main()
{
allocArrayOfStrings();
allocVectorOfStrings(); //This function crashes
return EXIT_SUCCESS;
}
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Dec 20 '07 #2

P: n/a
On Dec 20, 11:10 am, Rakesh Kumar <rakesh.use...@gmail.comwrote:
Hi All -
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);
for (size_t i = 0; i < vt->capacity(); ++i) {
std::cout << "We are probably ok" << i << "\n";
vt->operator[](i).reserve(40);
Try not to use new / delete unless you are required to do so.
You are attempting to access an element that doesn't yet exist.
reserve constructs nothing.
use vector's member function at(...) when in doubt. see below.
}
delete vt;

}

void allocArrayOfStrings() {
std::string * vt = new std::string[4096];
for (size_t i = 0; i < 1024; ++i) {
std::cout << "We are probably ok" << i << "\n";
vt[i].reserve(4096);
}
delete [] vt;

}

int main()
{
allocArrayOfStrings();
allocVectorOfStrings(); //This function crashes
return EXIT_SUCCESS;

}
#include <iostream>
#include <string>
#include <vector>
#include <stdexcept>

void allocVectorOfStrings()
{
std::vector<std::stringvt(10, "default string");
std::cout << "vt's size is " << vt.size() << std::endl;
for(size_t i = 0; i < vt.size(); ++i)
{
std::cout << "vt[ " << i << " ] ";
std::cout << vt.at(i) << std::endl;
}
// uncomment for a test
// vt.at(10) = "out or range";
}

int main()
{
try
{
allocVectorOfStrings();
}
catch( const std::exception& e)
{
std::cout << "Error:";
std::cout << e.what() << std::endl;
}
}

/*
vt's size is 10
vt[ 0 ] default string
....
vt[ 9 ] default string
*/
Dec 20 '07 #3

P: n/a
On Dec 20, 8:17 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Rakesh Kumar wrote:
Hi All -
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.
Thanks Victor.
The revised function seems to do what I intended in the first place.

void allocVectorOfStrings()
{
std::vector<std::stringvt(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.

>
}
delete vt;
}
void allocArrayOfStrings() {
std::string * vt = new std::string[4096];

Here 'vt' contains all 4096 elements.
for (size_t i = 0; i < 1024; ++i) {
std::cout << "We are probably ok" << i << "\n";

Yes, you are.
vt[i].reserve(4096);

'vt[i]' represents a real string. You can call 'reserve' for
it, no problem.
}
delete [] vt;
}
int main()
{
allocArrayOfStrings();
allocVectorOfStrings(); //This function crashes
return EXIT_SUCCESS;
}

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Dec 20 '07 #4

P: n/a
On Dec 20, 6:56 pm, Rakesh Kumar <rakesh.use...@gmail.comwrote:
On Dec 20, 8:17 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Rakesh Kumar wrote:
Hi All -
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.

Thanks Victor.
The revised function seems to do what I intended in the first place.

void allocVectorOfStrings()
{
std::vector<std::stringvt(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.
vt.resize( x );

After resize is used the vector will contain x elements. You could
also re-assign to it or use swap e.g:

vt = std::vector<std::string>( x ); //or

std::vector<std::stringv( x )
vt.swap( v );

I think resize would most probably be the best option though.

Regards,

Werner
Dec 20 '07 #5

This discussion thread is closed

Replies have been disabled for this discussion.