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

D

dalbosco

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\
ne’s 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);
}

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

Mike Wahler

dalbosco said:
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);


Here you dereference 'it'. Undefined behavior.

-Mike
 
V

Victor Bazarov

dalbosco said:
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);


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
 
B

Bob Hairgrove

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.
 
R

Ron Natalie

it = v.end();

v.end() is the "one past the end" value.
// CRASH HERE.
(*it)->insert((*it)->end(), data);
}

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.
 
D

dalbosco

dalbosco said:
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\
ne’s 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);
}

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.
 
R

Ron Natalie

dalbosco said:
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)...
 
V

Victor Bazarov

dalbosco said:
[...]
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
 
P

__PPS__

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.
 
V

Victor Bazarov

__PPS__ said:
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
 
O

Old Wolf

dalbosco said:
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,132
Latest member
TeresaWcq1
Top