Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > learner's question on populating vector< pair<int, string>* > asmember

Reply
Thread Tools

learner's question on populating vector< pair<int, string>* > asmember

 
 
subramanian100in@yahoo.com, India
Guest
Posts: n/a
 
      04-26-2008
Consider a class that has
vector< pair<int, string>* > c;
as member data object.

I need to use operator>> to store values into this container object
and
operator<< to print the contents of the container.

I have written both these operators as non-friend functions.

The destructor deletes all the pair<int, string> pointers in the
vector.

My doubt is that I am using a store_pair() function which allocates
memory
for each pair<int, string> pointer and stores into the container; but
the
dtor deletes these pointers thereby releasing the memory.

Kindly let me know if the approach in this program is correct.

Here is the full program:

#include <cstdlib>
#include <iostream>
#include <vector>
#include <utility>

using namespace std;

class Test
{
public:
Test();
~Test();

typedef pair<int, string> pair_type;
typedef vector<pair_type*> container_type;

void store_pair(const pair_type& arg);
const container_type& container() const { return c; }

private:
container_type c;
};

Test::Test() : c()
{
}

void Test::store_pair(const pair_type& arg)
{
pair_type* p = new pair_type(arg.first, arg.second);
c.push_back(p);
}

Test::~Test()
{
for (container_type::iterator it = c.begin(); it != c.end(); +
+it)
{
delete *it;
*it = 0;
}
}

istream& operator>>(istream& is, Test& obj)
{
while (is)
{
int x;
string str;
is >> x >> str;

if (is)
{
Test:air_type temp(x, str);
obj.store_pair(temp);
}
}

return is;
}

ostream& operator<<(ostream& os, const Test& obj)
{
for (Test::container_type::const_iterator it =
obj.container().begin();
it != obj.container().end();
++it)
os << (**it).first << " " << (*it)->second << endl;

return os;
}

int main()
{
Test obj;

cin >> obj;

cout << obj;

return EXIT_SUCCESS;
}

Thanks
V.Subramanian
 
Reply With Quote
 
 
 
 
osama178@gmail.com
Guest
Posts: n/a
 
      04-26-2008
On Apr 25, 8:29*pm, "subramanian10...@yahoo.com, India"
<subramanian10...@yahoo.com> wrote:
> Consider a class that has
> vector< pair<int, string>* > *c;
> as member data object.
>
> I need to use operator>> to store values into this container object
> and
> operator<< to print the contents of the container.
>
> I have written both these operators as non-friend functions.
>
> The destructor deletes all the pair<int, string> pointers in the
> vector.
>
> My doubt is that I am using a store_pair() function which allocates
> memory
> for each pair<int, string> pointer and stores into the container; but
> the
> dtor deletes these pointers thereby releasing the memory.
>
> Kindly let me know if the approach in this program is correct.
>
> Here is the full program:
>
> #include <cstdlib>
> #include <iostream>
> #include <vector>
> #include <utility>
>
> using namespace std;
>
> class Test
> {
> public:
> Test();
> ~Test();
>
> typedef pair<int, string> pair_type;
> typedef vector<pair_type*> container_type;
>
> void store_pair(const pair_type& arg);
> const container_type& container() const { return c; }
>
> private:
> container_type c;
>
> };
>
> Test::Test() : c()
> {
>
> }
>
> void Test::store_pair(const pair_type& arg)
> {
> * * * * pair_type* p = new pair_type(arg.first, arg.second);
> * * * * c.push_back(p);
>
> }
>
> Test::~Test()
> {
> * * * * for (container_type::iterator it = c.begin(); it != c.end(); +
> +it)
> * * * * {
> * * * * * * * * delete *it;
> * * * * * * * * *it = 0;
> * * * * }
>
> }
>
> istream& operator>>(istream& is, Test& obj)
> {
> * * * * while (is)
> * * * * {
> * * * * * * * * int x;
> * * * * * * * * string str;
> * * * * * * * * is >> x >> str;
>
> * * * * * * * * if (is)
> * * * * * * * * {
> * * * * * * * * * * * * Test:air_type temp(x, str);
> * * * * * * * * * * * * obj.store_pair(temp);
> * * * * * * * * }
> * * * * }
>
> * * * * return is;
>
> }
>
> ostream& operator<<(ostream& os, const Test& obj)
> {
> * * * * for (Test::container_type::const_iterator it =
> obj.container().begin();
> * * * * * * * it != obj.container().end();
> * * * * * * * ++it)
> * * * * * * * * os << (**it).first << " * " << (*it)->second << endl;
>
> * * * * return os;
>
> }
>
> int main()
> {
> * * * * Test obj;
>
> * * * * cin >> obj;
>
> * * * * cout << obj;
>
> * * * * return EXIT_SUCCESS;
>
> }
>
> Thanks
> V.Subramanian


#include<string> in your program and it should work fine.
 
Reply With Quote
 
 
 
 
Ian Collins
Guest
Posts: n/a
 
      04-26-2008
wrote:
>
> #include<string> in your program and it should work fine.


Did you have to quote the entire message just to add that?

--
Ian Collins.
 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      04-26-2008
, India wrote:
> Consider a class that has
> vector< pair<int, string>* > c;
> as member data object.
>
> I need to use operator>> to store values into this container object
> and
> operator<< to print the contents of the container.
>
> I have written both these operators as non-friend functions.
>
> The destructor deletes all the pair<int, string> pointers in the
> vector.
>
> My doubt is that I am using a store_pair() function which allocates
> memory
> for each pair<int, string> pointer and stores into the container; but
> the
> dtor deletes these pointers thereby releasing the memory.
>
> Kindly let me know if the approach in this program is correct.
>

It is one option, but consider just storing small objects (like your
pair<int, string>) in the vector rather than pointers. Then you won't
have to bother deleting them or copying a temporary object in your inserter.

--
Ian Collins.
 
Reply With Quote
 
osama178@gmail.com
Guest
Posts: n/a
 
      04-26-2008
>
> Did you have to quote the entire message just to add that?
>
> --
> Ian Collins.


opps. I could swear I did not quote the message at all, but I have to
learn to double-check for next time.

Thanks for the tip.
 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      04-26-2008
wrote:
>> Did you have to quote the entire message just to add that?
>>
>> --
>> Ian Collins.

>
> opps. I could swear I did not quote the message at all, but I have to
> learn to double-check for next time.
>
> Thanks for the tip.


OK, while we're here, it's bad form to quote signatures (the bit after
the "-- ").

--
Ian Collins.
 
Reply With Quote
 
osama178@gmail.com
Guest
Posts: n/a
 
      04-26-2008
> OK, while we're here, it's bad form to quote signatures (the bit after
> the "-- ").


I hope I got it right this time. Ok, I'll read the FAQ guidelines
again:
http://www.parashift.com/c++-faq-lite/how-to-post.html



 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      04-28-2008
, India wrote:
> Consider a class that has
> vector< pair<int, string>* > c;
> as member data object.


> I need to use operator>> to store values into this container
> object and operator<< to print the contents of the container.


> I have written both these operators as non-friend functions.


> The destructor deletes all the pair<int, string> pointers in
> the vector.


> My doubt is that I am using a store_pair() function which
> allocates memory for each pair<int, string> pointer and stores
> into the container; but the dtor deletes these pointers
> thereby releasing the memory.


And what do you doubt about that? (I have doubts about the
wisdom of storing pointers, rather than the objects themselves,
given that std:air has value semantics, but that's a different
issue.)

> Kindly let me know if the approach in this program is correct.


> Here is the full program:


> #include <cstdlib>
> #include <iostream>
> #include <vector>
> #include <utility>


> using namespace std;


> class Test
> {
> public:
> Test();
> ~Test();


> typedef pair<int, string> pair_type;
> typedef vector<pair_type*> container_type;


> void store_pair(const pair_type& arg);
> const container_type& container() const { return c; }


I also have a lot of doubts about exposing the implementation
like this. If you're going to do this, you might as well make
the container public, and be done with it.

> private:
> container_type c;
> };


> Test::Test() : c()
> {
> }


> void Test::store_pair(const pair_type& arg)
> {
> pair_type* p = new pair_type(arg.first, arg.second);
> c.push_back(p);


What's wrong with simply:
c.push_ back( new pair_type( arg ) ) ;
?

> }


> Test::~Test()
> {
> for (container_type::iterator it = c.begin(); it != c.end(); +
> +it)
> {
> delete *it;
> *it = 0;


Formally (but only formally), this is undefined behavior. You
must set the pointer in the container to null before the delete.

Practically, of course, there'll never be an implementation
where it will cause any problems, so I wouldn't worry about it.
For that matter, I wouldn't worry about setting the pointer to
null, since there'll never be an implementation where not doing
so will cause problems either, so I wouldn't worry about that
either.

> }
> }


> istream& operator>>(istream& is, Test& obj)
> {
> while (is)
> {
> int x;
> string str;
> is >> x >> str;


> if (is)
> {
> Test:air_type temp(x, str);
> obj.store_pair(temp);
> }
> }
> return is;
> }


The real question is what semantics you want. Generally
speaking, I have my doubts about the format you're inputting; I
can't think of a context where it would be appropriate. But
what is appropriate depends on the application. Until you've
defined the format, it's impossible to say whether this is
correct or not.

> ostream& operator<<(ostream& os, const Test& obj)
> {
> for (Test::container_type::const_iterator it =
> obj.container().begin();
> it != obj.container().end();
> ++it)
> os << (**it).first << " " << (*it)->second << endl;


Why the two different ways to access the pair? Choose one, and
use it consistently. (I'd use the second, but that's more a
question of personal preference.)

> return os;
> }


--
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
 
Reply With Quote
 
Triple-DES
Guest
Posts: n/a
 
      04-29-2008
On 28 Apr, 10:10, James Kanze <james.ka...@gmail.com> wrote:
> subramanian10...@yahoo.com, India wrote:
> > Test::~Test()
> > {
> > * * * * for (container_type::iterator it = c.begin(); it != c.end(); +
> > +it)
> > * * * * {
> > * * * * * * * * delete *it;
> > * * * * * * * * *it = 0;

>
> Formally (but only formally), this is undefined behavior. *You
> must set the pointer in the container to null before the delete.
>


Why is that?
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      04-29-2008
On Apr 29, 7:41 am, Triple-DES <DenPlettf...@gmail.com> wrote:
> On 28 Apr, 10:10, James Kanze <james.ka...@gmail.com> wrote:


> > subramanian10...@yahoo.com, India wrote:
> > > Test::~Test()
> > > {
> > > for (container_type::iterator it = c.begin(); it != c.end(); +
> > > +it)
> > > {
> > > delete *it;
> > > *it = 0;


> > Formally (but only formally), this is undefined behavior. You
> > must set the pointer in the container to null before the delete.


> Why is that?


Because all objects in a container must be copiable, and a
deleted pointer is not copiable. In practice, of course

-- I don't know of any implementation today where copying a
deleted pointer will actually cause problems (although some
have definitely existed in the past), and above all

-- the implementation of std::vector is not going to copy an
element without reason, and as long as you don't extend the
vector, or explicitly do something which reads the value,
there's no reason.

So while I wouldn't leave a deleted pointer in an std::vector
which will remain live, I don't think you have to worry about
any problems between deleting it and assigning null, if they
immediately follow one another, nor any problems if the delete's
are preliminary to calling the vector's destructor (as is the
case here---there's no real reason to even assign 0 in this
case).

--
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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
populating a 2D array question Zach C Programming 14 12-10-2010 01:40 AM
beginner question: populating a form Mr. T. ASP .Net 1 01-30-2006 08:54 PM
beginner question: populating a form Mr. T. ASP .Net 0 01-30-2006 08:01 PM
[Newbie Question] Populating Textbox.text from a dataview using columnnames? DC ASP .Net 0 06-15-2005 02:43 PM
Newbie Question: Pre-populating the Command Line History Buffer CJ Morton Cisco 3 11-03-2003 11:00 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57