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

std::vector<string*> crash...

P: n/a
Hello,
I am new to STL and I've written the following code
which crash.
Could anyone tell me why this code crash?
Thanks by advance.
--
J-F
#include <iostream>
#include <vector>

using namespace std;

static char data[] =
"Because the original quantities and instructions \
that make up Linux have been published, \
any programmer can see what it is doing,\
how it does it and, possibly, how it cou\
ld do it better. Torvalds did not invent\
the concept of open programming but Linu\
x is its first success story. Indeed, it\
probably could not have succeeded befor\
e the Internet had linked the disparate\
world of computing experts. In making \
Linux an open language, Torvalds gave \
up the opportunity of growing rich fro\
m his work. This too is part of nerd c\
ulture, which thrives on the satisfact\
ion of authorship and the respect of o\
nes peers.";

static const int line_length = 10;

int
main(int argc, char** argv)
{
string* str = NULL;
vector<string*> v;
vector<string*>::iterator it;

for( int i = 0; i < sizeof(data) / sizeof(data[0]); i++)
{
if( 0 == ((i+1) % line_length))
{
// Every "line_length" char create a new
// string which will hold place for the line.

str = new string;
str->insert(str->end(), 'a');
v.insert(v.end(), str);
}

it = v.end();
// CRASH HERE.
(*it)->insert((*it)->end(), data[i]);
}

for(it = v.begin(); it != v.end(); it++)
{
cout << **it << endl;
delete(*it);
}
}
Jul 22 '05 #1
Share this Question
Share on Google+
10 Replies


P: n/a

"dalbosco" <da******@free.fr> wrote in message
news:41***********************@news.free.fr...
Hello,
I am new to STL and I've written the following code
which crash.
Could anyone tell me why this code crash? int
main(int argc, char** argv)
{
string* str = NULL;
vector<string*> v;
vector<string*>::iterator it;

for( int i = 0; i < sizeof(data) / sizeof(data[0]); i++)
{
if( 0 == ((i+1) % line_length))
{
// Every "line_length" char create a new
// string which will hold place for the line.

str = new string;
str->insert(str->end(), 'a');
v.insert(v.end(), str);
}

it = v.end();
Now 'it' is pointing outside the vector. It does not
refer to a valid object.
// CRASH HERE.
(*it)->insert((*it)->end(), data[i]);


Here you dereference 'it'. Undefined behavior.

-Mike
Jul 22 '05 #2

P: n/a
dalbosco wrote:
Hello,
I am new to STL and I've written the following code
which crash.
Could anyone tell me why this code crash?
Thanks by advance.
--
J-F
#include <iostream>
#include <vector>

using namespace std;

static char data[] =
"[...]";

static const int line_length = 10;

int
main(int argc, char** argv)
{
string* str = NULL;
vector<string*> v;
Why in the world do you need a vector of _pointers_? Why not just
a vector of strings?
vector<string*>::iterator it;

for( int i = 0; i < sizeof(data) / sizeof(data[0]); i++)
{
if( 0 == ((i+1) % line_length))
{
// Every "line_length" char create a new
// string which will hold place for the line.
str = new string;
str->insert(str->end(), 'a');
Why do you need this instead of, say,

str->append('a');

?
v.insert(v.end(), str);
This is much better written

v.push_back(str);

it's much easier to understand that.
}

it = v.end();
// CRASH HERE.
(*it)->insert((*it)->end(), data[i]);
What are you trying to achieve here? Perhaps you wanted to use
'v.rbegin()' instead of 'v.end()' if you need the iterator to the
_last_ element of the vector. 'v.end()' returns the "one-past-the-
end" iterator.

RTFM
}

for(it = v.begin(); it != v.end(); it++)
{
cout << **it << endl;
delete(*it);
}
}

Jul 22 '05 #3

P: n/a
On Fri, 22 Oct 2004 19:39:04 +0200, dalbosco <da******@free.fr> wrote:
Hello,
I am new to STL and I've written the following code
which crash.
Could anyone tell me why this code crash?
Thanks by advance.


You don't use line continuations (backslash) when writing actual code,
only when writing macros (#define ...)

Try this instead:

static char data[] =
"Because the original quantities and instructions "
"that make up Linux have been published, "
"any programmer can see what it is doing,"

etc.

The compiler just concatenates the lines automatically. If you want
real line breaks, you need to embed '\n' in the data.

--
Bob Hairgrove
No**********@Home.com
Jul 22 '05 #4

P: n/a
it = v.end();
v.end() is the "one past the end" value. // CRASH HERE.
(*it)->insert((*it)->end(), data[i]);
}

There is no object *it.

Further I believe in your code you have NOTHING in the
vector the first time through. When i is initially
0, the if statement condition is false.

I'm not clear what you are trying to do...but the fact
that you have all these pointers to strings pretty much
indicates that you're going about it the wrong way.
Jul 22 '05 #5

P: n/a
dalbosco wrote:
Hello,
I am new to STL and I've written the following code
which crash.
Could anyone tell me why this code crash?
Thanks by advance.
--
J-F
#include <iostream>
#include <vector>

using namespace std;

static char data[] =
"Because the original quantities and instructions \
that make up Linux have been published, \
any programmer can see what it is doing,\
how it does it and, possibly, how it cou\
ld do it better. Torvalds did not invent\
the concept of open programming but Linu\
x is its first success story. Indeed, it\
probably could not have succeeded befor\
e the Internet had linked the disparate\
world of computing experts. In making \
Linux an open language, Torvalds gave \
up the opportunity of growing rich fro\
m his work. This too is part of nerd c\
ulture, which thrives on the satisfact\
ion of authorship and the respect of o\
nes peers.";

static const int line_length = 10;

int
main(int argc, char** argv)
{
string* str = NULL;
vector<string*> v;
vector<string*>::iterator it;

for( int i = 0; i < sizeof(data) / sizeof(data[0]); i++)
{
if( 0 == ((i+1) % line_length))
{
// Every "line_length" char create a new
// string which will hold place for the line.
str = new string;
str->insert(str->end(), 'a');
v.insert(v.end(), str);
}

it = v.end();
// CRASH HERE.
(*it)->insert((*it)->end(), data[i]);
}

for(it = v.begin(); it != v.end(); it++)
{
cout << **it << endl;
delete(*it);
}
}


OK i finally wen't through and v.rbegin() was the solution.
BTW I'm not scared by pointer. They avoid useless in-memory
copies while passing parameters.
--
JF

Victor :
RTFM too. std::string::append() takes a char* and not a char.
Thank you anyway.
Jul 22 '05 #6

P: n/a
dalbosco wrote:

OK i finally wen't through and v.rbegin() was the solution.
BTW I'm not scared by pointer. They avoid useless in-memory
copies while passing parameters


What useless in-memory copy? If you resize the vector and then
insert characters into the string that's IN the vector (operator[],
front() and back() all return references)...
Jul 22 '05 #7

P: n/a
dalbosco wrote:
[...]
Victor :
RTFM too. std::string::append() takes a char* and not a char.
Thank you anyway.


Just to let you know. There are five variations of std::string::append
and if you RTFM long enough and hard enough you will find one that takes
'char' as one of its arguments. I'll leave it to you to find.

V
Jul 22 '05 #8

P: n/a
There is no point in using "new string(...)" use then plain new
char[x] instead if you have desire to manage memory (and write the
code for that) yourself.
a string object itself is only ~ 30-40 bytes of which most of the part
is a static buffer. it stores pointer (or whatever) to the data that
is automatically (de)allocated. So, why then would you want to new
them if this process happens inside them... Just read some book and
try to do it the way it's explained in the book.
Jul 22 '05 #9

P: n/a
__PPS__ wrote:
There is no point in using "new string(...)" use then plain new
char[x] instead if you have desire to manage memory (and write the
code for that) yourself.
Well, that's not totally true. The point of using a string instead of
a plain char* would be to use string's ability to grow if necessary, and
not having to reallocate the memory. Going "all the way" with dynamic
memory allocation is often problematic for Java programmers crossing
over to C++ because they are used to doing 'new Thing' all the time and
rarily do 'new Thing[blah]'. I'm generalising, of course, and it's
probably a wrong thing to do :*)
a string object itself is only ~ 30-40 bytes of which most of the part
is a static buffer. it stores pointer (or whatever) to the data that
is automatically (de)allocated. So, why then would you want to new
them if this process happens inside them... Just read some book and
try to do it the way it's explained in the book.


Reading a good book would be preferrable to reading "some book". I am
sure you meant that.

V
Jul 22 '05 #10

P: n/a
dalbosco <da******@free.fr> wrote:
dalbosco wrote:
vector<string*> v;
vector<string*>::iterator it;

str = new string;
str->insert(str->end(), 'a');
v.insert(v.end(), str);


BTW I'm not scared by pointer. They avoid useless in-memory
copies while passing parameters.


Actually they use more memory here. Instead of N strings you
have N strings and N pointers. What's worse though, instead of
one block of memory with N strings, you have N blocks of memory.
If your allocator has a minimum allocation size (most do AFAIK)
then you have wasted some bytes. Also you have increased
fragmentation of the memory pool (thus degrading OS performance).

Also your posted code has no instances of a 'passing parameter'
that would have saved time or memory by using pointers. For
example, passing by reference is either the same or better
than passing by pointer.
Jul 22 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.