473,326 Members | 2,127 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,326 software developers and data experts.

what is happening to elements in vector ?

I have a std::vector with each element being a class, I push_back
elements and then store values in the class object, later I look at
these objects and the values are null. In essence:

class celement
{
public:
int x[3];
...

class vec
{
public:
std::vector<celementv;
...

void vec::addelement()
{
celement t;
v.push_back(t);
}

void vec::buildmono()
{
addelement();
v.end() -x[0] = -1;
...

void vec::buildmono()
{
for (i = 0; i < 10; i++)
buildmono();

Later I look through v and none of x[0]s are -1 they are all 0.
for (i = 0; i < 10; i++)
cout << v[i].x[0] ..
If there is no obvious explanation then I can post more code.

Sep 24 '06 #1
8 1679
Hi,

I didn't look at your code carefully (it's quite late here) but I saw

v.end()->

v.end() is pointing one past the last element, i.e.illegal

make that

v.rbegin()->


Regards, Ron AF Greve

http://moonlit.xs4all.nl

<im*****@hotmail.co.ukwrote in message
news:11**********************@m73g2000cwd.googlegr oups.com...
>I have a std::vector with each element being a class, I push_back
elements and then store values in the class object, later I look at
these objects and the values are null. In essence:

class celement
{
public:
int x[3];
..

class vec
{
public:
std::vector<celementv;
..

void vec::addelement()
{
celement t;
v.push_back(t);
}

void vec::buildmono()
{
addelement();
v.end() -x[0] = -1;
..

void vec::buildmono()
{
for (i = 0; i < 10; i++)
buildmono();

Later I look through v and none of x[0]s are -1 they are all 0.
for (i = 0; i < 10; i++)
cout << v[i].x[0] ..
If there is no obvious explanation then I can post more code.

Sep 24 '06 #2

Moonlit wrote:
make that

v.rbegin()->

Thanks, that worked, although I found it easier to use push_back(x)
with x already set to what I wanted.

Sep 24 '06 #3

im*****@hotmail.co.uk wrote:
I have a std::vector with each element being a class, I push_back
elements and then store values in the class object, later I look at
these objects and the values are null. In essence:
std::vectors don't store classes, they store instances of a class.
Beware of instances that are default constructed without the use of a
default ctor. You'll get surprises.

The celement class should encapsulate your integers and in a case like
this you should keep the integers seperate. Why? Because then you'll
have control over what a default object looks like without having to
initialize the array in its ctor. Use an init list instead.

#include <iostream>
#include <ostream>
#include <vector>

class celement
{
int x, y, z;
public:
celement() : x(0), y(0), z(0) { } // default ctor w init list
celement( int x_, int y_, int z_ ) : x(x_), y(y_), z(z_) { }
~celement() { }
/* friend function */
friend
std::ostream& operator<<( std::ostream&, const celement& );
};

/* global op<< oveload for celement */
std::ostream& operator<<( std::ostream& os, const celement& ce )
{
os << "x = " << ce.x;
os << ", y = " << ce.y;
os << ", z = " << ce.z;
return os << std::endl;
}

class vec
{
std::vector< celement v;
public:
vec() : v() { }
vec(size_t sz) : v(sz) { } // preset size of vector with def
elements
~vec() { }
size_t size() const { return v.size(); }
void push_back( const celement& ce ) { v.push_back( ce ); }
celement& operator[]( unsigned index ) { return v[index]; }
};

int main()
{
vec container(5);
container.push_back( celement(10,11,12) );
std::cout << "container's size = " << container.size();
std::cout << std::endl;

for ( size_t i = 0; i < container.size(); ++i)
{
std::cout << "container[ " << i << " ] ";
std::cout << container[ i ];
}
return 0;
}

/*
container's size = 6
container[ 0 ] x = 0, y = 0, z = 0
container[ 1 ] x = 0, y = 0, z = 0
container[ 2 ] x = 0, y = 0, z = 0
container[ 3 ] x = 0, y = 0, z = 0
container[ 4 ] x = 0, y = 0, z = 0
container[ 5 ] x = 10, y = 11, z = 12
*/

I'm ignoring the need that celement should have and assignment op for
now.

Sep 24 '06 #4

Salt_Peter wrote:
im*****@hotmail.co.uk wrote:
I have a std::vector with each element being a class, I push_back
elements and then store values in the class object, later I look at
these objects and the values are null. In essence:

std::vectors don't store classes, they store instances of a class.
OK, my bad wording.
Beware of instances that are default constructed without the use of a
default ctor. You'll get surprises.
Do you mean I have to provide a constructor ?
Even if I assigned afterwards it could cause problems ?

celement c;
vec.push_back(c);
... later c out of scope
vec.rbegin() -x[0] = 10;
class vec
{
std::vector< celement v;
public:
vec() : v() { }
vec(size_t sz) : v(sz) { } // preset size of vector with def
elements
~vec() { }
size_t size() const { return v.size(); }
void push_back( const celement& ce ) { v.push_back( ce ); }
celement& operator[]( unsigned index ) { return v[index]; }
};
Won't you get all these anyway ? Why "present" them to the compiler ?

Sep 24 '06 #5
im*****@hotmail.co.uk wrote:
Salt_Peter wrote:
im*****@hotmail.co.uk wrote:
I have a std::vector with each element being a class, I push_back
elements and then store values in the class object, later I look at
these objects and the values are null. In essence:
std::vectors don't store classes, they store instances of a class.

OK, my bad wording.
Beware of instances that are default constructed without the use of a
default ctor. You'll get surprises.

Do you mean I have to provide a constructor ?
Even if I assigned afterwards it could cause problems ?
Not neccessarily, but keep in mind that some compilers will default
initialize an integer, for example, to 0 in debug and leave it
unitialized in release mode. Besides, why assign it later when you can
do it at construction time?
>
celement c;
vec.push_back(c);
.. later c out of scope
vec.rbegin() -x[0] = 10;
It doesn't matter if c is out of scope, the vector stores an
independant copy of it.
>
class vec
{
std::vector< celement v;
public:
vec() : v() { }
vec(size_t sz) : v(sz) { } // preset size of vector with def
elements
~vec() { }
size_t size() const { return v.size(); }
void push_back( const celement& ce ) { v.push_back( ce ); }
celement& operator[]( unsigned index ) { return v[index]; }
};

Won't you get all these anyway ? Why "present" them to the compiler ?
The std::vector is private. The goal is to prevent the user of the
class from directly accessing the components within. As an example, you
can overload vec::push_back(...) to take 3 integer parameters instead
of a celement. You might choose to provide a vec ctor that takes an
array of celements. You could overload a friend operator<< that
iterates through the container seamleassly. The point is that the user
of the class will find it harder to break the container if you protect
its internals.

class vec
{
std::vector< celement v;
public:
vec() : v() { }
vec(size_t sz) : v(sz) { } // preset size of vector
~vec() { }
size_t size() const { return v.size(); }
void push_back( const celement& ce ) { v.push_back( ce ); }
void push_back( int x, int y, int z ) { v.push_back( celement(x, y,
z) ); }
celement& operator[]( unsigned index ) { return v[index]; }
/* friend function */
friend
std::ostream& operator<<( std::ostream&, const vec& );
};

std::ostream& operator<<( std::ostream& os, const vec& r_v )
{
std::cout << "container's size = " << r_v.v.size();
std::cout << std::endl;
typedef std::vector< celement >::const_iterator VIter;
VIter iter = r_v.v.begin();
for ( iter; iter != r_v.v.end(); ++iter )
{
os << *iter;
}
return os;
}

int main()
{
vec container;
celement def;
container.push_back( def );
container.push_back( celement(0, 1, 2) );
container.push_back( 10, 11, 12 );
celement ce( 20, 30, 40 );
container.push_back( ce );
// container.v.clear(); // error: vec::v is private

std::cout << container; // one line for output !!!
return 0;
}

/*
container's size = 4
x = 0, y = 0, z = 0
x = 0, y = 1, z = 2
x = 10, y = 11, z = 12
x = 20, y = 30, z = 40
*/

Sep 24 '06 #6
Not neccessarily, but keep in mind that some compilers will default
initialize an integer, for example, to 0 in debug and leave it
unitialized in release mode.
OK, deceptive, but not particularly unusual in computer systems in
general for initialise values to be non 0 or null.
Besides, why assign it later when you can
do it at construction time?
Constructors that assign values make for nice textbook code, but in
practice if you have objects of any complexity you will probably want
to initialise them from disk ( database etc) probably more than once.
So writing constructor code just makes for more work.
>
The std::vector is private. The goal is to prevent the user of the
class from directly accessing the components within. As an example, you
can overload vec::push_back(...) to take 3 integer parameters instead
of a celement. You might choose to provide a vec ctor that takes an
array of celements.
OK, but why not make a member to "initialise" the object and then call
that from the constructor, that way I don't have to create a new object
just clear it (if neccessary) and call initialise again.

Thanks, for the example.

Sep 24 '06 #7

im*****@hotmail.co.uk wrote:
Not neccessarily, but keep in mind that some compilers will default
initialize an integer, for example, to 0 in debug and leave it
unitialized in release mode.

OK, deceptive, but not particularly unusual in computer systems in
general for initialise values to be non 0 or null.
Note that released, optimized code does not initialize at all unless
the ctor does some sort of default construction. Uninitialized objects
are dangerous since the residual bits that are contained in the object
are used if the instance is operated on. That, in essence, is a common
bug.

Doesn't the compiler have to generate a ctor anyway? Same with copy
ctor, d~tor, etc. Why not take control of what the compiler does?
Consider a class that stores a pointer that is left unitialized by
mistake.
What if you wrote the class's ctor to default initialize the pointer to
0 instead?
The moment you, me or an unsuspecting user of the class makes the
mistake of using an instance of P without setting it: the compiler
generates an error that instantly and precisely diagnoses the problem
(null pointer exception). In the long run, its less work cause you
don't have to split your brains looking for the hard to find bugs. Its
safety built-in to the design. And your clients will love you for it.
>
Besides, why assign it later when you can
do it at construction time?

Constructors that assign values make for nice textbook code, but in
practice if you have objects of any complexity you will probably want
to initialise them from disk ( database etc) probably more than once.
So writing constructor code just makes for more work.
The ctor is invoked when reading the data from disk directly. In other
words, when the std::ifstream opens the file: it's contents are
seamlessly used to construct (or even reinitialize) the object or its
elements.

The std::vector is private. The goal is to prevent the user of the
class from directly accessing the components within. As an example, you
can overload vec::push_back(...) to take 3 integer parameters instead
of a celement. You might choose to provide a vec ctor that takes an
array of celements.

OK, but why not make a member to "initialise" the object and then call
that from the constructor, that way I don't have to create a new object
just clear it (if neccessary) and call initialise again.
There is no reason why not. Using some init() member function is
perfectly safe. Which brings us to the core of the issue. The ctor
already supports the init list. I can think of several languages who
would DIE to have the benefits of the init list.

class N
{
int n; // n could be a complex user-type instead
public:
N() : n( initialize() ) { } // perfectly legal
~N() { }
int initialize() const { return 100; } // or whatever is required
};

That way, you can reserve the body of the ctor (and d~tor) for usefull
diagnostics when you are developing the project. as in:

N::N() : n( initialize() ) { std::cout << "N()\n"; }
N::~N() { std::cout << "~N()\n"; }

Which may look trivial at this point but very handy when dealing with
polymorphism and deallocations (you know... memory leaks).
>
Thanks, for the example.
Your welcome, and give yourself some credits. You at least showed some
code.

Sep 25 '06 #8

Salt_Peter wrote:
Note that released, optimized code does not initialize at all unless
the ctor does some sort of default construction. Uninitialized objects
are dangerous since the residual bits that are contained in the object
are used if the instance is operated on. That, in essence, is a common
bug.
OK. But are you saying that even if I set every variable then there
could be some circumstance where it gets corrupted because of no
implemented ctor ?
Doesn't the compiler have to generate a ctor anyway? Same with copy
ctor, d~tor, etc. Why not take control of what the compiler does?
Consider a class that stores a pointer that is left unitialized by
mistake.
What if you wrote the class's ctor to default initialize the pointer to
0 instead?
The moment you, me or an unsuspecting user of the class makes the
mistake of using an instance of P without setting it: the compiler
generates an error that instantly and precisely diagnoses the problem
(null pointer exception). In the long run, its less work cause you
don't have to split your brains looking for the hard to find bugs. Its
safety built-in to the design. And your clients will love you for it.
Yep, default values are great on interfaces.
The ctor is invoked when reading the data from disk directly. In other
words, when the std::ifstream opens the file: it's contents are
seamlessly used to construct (or even reinitialize) the object or its
elements.
I did not know that. I will read up about ifstream.
>
There is no reason why not. Using some init() member function is
<snip>
OK I saw some pitfalls in the C++ faq about one ctor calling another,
but this way will avoid those.
>
Your welcome, and give yourself some credits. You at least showed some
code.
Here is some more, not mine but from supposedly from Stroustrup.
I was wondering you could wrap up std::vector in a similar way..

template < typename T, int max >
struct c_array
{
typedef T value_type;
typedef T* iterator;
typedef const T* const_iterator;
typedef T& reference;
typedef const T& const_reference;
T v[max];
....
google "c_array template c++ Stroustrup" to see the rest.

Sep 25 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: Generic Usenet Account | last post by:
To settle the dispute regarding what happens when an "erase" method is invoked on an STL container (i.e. whether the element is merely removed from the container or whether it also gets deleted in...
12
by: Steven T. Hatton | last post by:
This is something I've been looking at because it is central to a currently broken part of the KDevelop new application wizard. I'm not complaining about it being broken, It's a CVS images. ...
11
by: Richard Thompson | last post by:
I've got a memory overwrite problem, and it looks as if a vector has been moved, even though I haven't inserted or deleted any elements in it. Is this possible? In other words, are there any...
6
by: Matthias | last post by:
Hi, say I have a vector v1: std::vector<SomeType> v1; and I need a vector v2 of pointers to v1's elements: std::vector<SomeType*> v2;
6
by: Alfonso Morra | last post by:
I have written the following code, to test the concept of storing objects in a vector. I encounter two run time errors: 1). myClass gets destructed when pushed onto the vector 2). Prog throws a...
8
by: Narf the Mouse | last post by:
I'm currently working on a roguelike as an excercise in learning c++. Anyway, I've set up a script parser to check a text file to find out how many races there are, then dynamically alocate an...
4
by: Christian Bruckhoff | last post by:
Hi. Is there a possibility to delete elements out of a vector? At the moment i do it by copying all needed elements to another vector. After clearing the old vector i copy them back element by...
1
by: Alan | last post by:
I am wondering if anyone has any better idea of how to approach this problem than I do. . . . I have a vector of items (data). I have to do a pairwise comparison of each item to each other item...
19
by: arnuld | last post by:
/* C++ Primer - 4/e * chapter 4- Arrays & Pointers, exercise 4.28 * STATEMENT * write a programme to read the standard input and build a vector of integers from values that are read....
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.