Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > delete map elements

Reply
Thread Tools

delete map elements

 
 
David
Guest
Posts: n/a
 
      03-17-2007
Hi all,

I try to use map container and delete the elements. but there are
something wrong, please help me check it.

class test{
protected:
map<string,myclass*> tests;

public:
test();
void AddMyclass(const string& myname,const myclass &st);
~test();
};

suppose myclass has been defined before.

and
test::~test()
{
map<string,myclass*>::iterator ii;
for(ii=tests.begin();ii!=tests.end();++ii)
{
delete(ii->second);
}
tests.clear();
}
int main()
{
test my;
myclass st;
my.AddMyclass("new class",st);
}
But when the code exits from the main function, there was an error
message saying that "Object reference not set to an instance of an
object.".

I think it is caused by the test's destructor function. But I don't
know where is the problem. Please help me. Thanks

 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      03-17-2007
David wrote:
> I try to use map container and delete the elements. but there are
> something wrong, please help me check it.
>
> class test{
> protected:
> map<string,myclass*> tests;
>
> public:
> test();
> void AddMyclass(const string& myname,const myclass &st);


What's the implementation of it? What do you do with 'st'? The
only allowed thing here is a copy-construction in the free store:

...
tests.insert(make_pair(myname, new myclass(st)));
...

> ~test();
> };
>
> suppose myclass has been defined before.
>
> and
> test::~test()
> {
> map<string,myclass*>::iterator ii;
> for(ii=tests.begin();ii!=tests.end();++ii)
> {
> delete(ii->second);


You are only allowed to use 'delete' with a pointer you obtained
by using 'new'. Did you?

> }
> tests.clear();


No need to call 'clear'. The map is going to be destroyed anyway.

> }
> int main()
> {
> test my;
> myclass st;
> my.AddMyclass("new class",st);
> }
> But when the code exits from the main function, there was an error
> message saying that "Object reference not set to an instance of an
> object.".
>
> I think it is caused by the test's destructor function. But I don't
> know where is the problem. Please help me. Thanks


You have not shown us the *complete* program. Read FAQ 5.8. The
error is logical, most likely. If you just try to store the _address_
of the local 'st' object, you are not allowed to use 'delete' on it.

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


 
Reply With Quote
 
 
 
 
David
Guest
Posts: n/a
 
      03-17-2007
On Mar 17, 11:32 am, "Victor Bazarov" <(E-Mail Removed)> wrote:
> David wrote:
> > I try to use map container and delete the elements. but there are
> > something wrong, please help me check it.

>
> > class test{
> > protected:
> > map<string,myclass*> tests;

>
> > public:
> > test();
> > void AddMyclass(const string& myname,const myclass &st);

>
> What's the implementation of it? What do you do with 'st'? The
> only allowed thing here is a copy-construction in the free store:
>
> ...
> tests.insert(make_pair(myname, new myclass(st)));
> ...
>
> > ~test();
> > };

>
> > suppose myclass has been defined before.

>
> > and
> > test::~test()
> > {
> > map<string,myclass*>::iterator ii;
> > for(ii=tests.begin();ii!=tests.end();++ii)
> > {
> > delete(ii->second);

>
> You are only allowed to use 'delete' with a pointer you obtained
> by using 'new'. Did you?
>
> > }
> > tests.clear();

>
> No need to call 'clear'. The map is going to be destroyed anyway.
>
> > }
> > int main()
> > {
> > test my;
> > myclass st;
> > my.AddMyclass("new class",st);
> > }
> > But when the code exits from the main function, there was an error
> > message saying that "Object reference not set to an instance of an
> > object.".

>
> > I think it is caused by the test's destructor function. But I don't
> > know where is the problem. Please help me. Thanks

>
> You have not shown us the *complete* program. Read FAQ 5.8. The
> error is logical, most likely. If you just try to store the _address_
> of the local 'st' object, you are not allowed to use 'delete' on it.
>
> V
> --
> Please remove capital 'A's when replying by e-mail
> I do not respond to top-posted replies, please don't ask


Sorry I forget the function AddMyclass();
void test::AddMyclass(const string &myname,const myclass &st)
{
map<string,myclass*>:;iterator ii;
myclass *newmyclass=NULL;
newmyclass=new myclass(st);
tests[myname]=newmyclass;
}

Thanks,

 
Reply With Quote
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      03-17-2007
David wrote:

> Hi all,
>
> I try to use map container and delete the elements. but there are
> something wrong, please help me check it.
>
> class test{
> protected:
> map<string,myclass*> tests;
>
> public:
> test();
> void AddMyclass(const string& myname,const myclass &st);
> ~test();
> };
>
> suppose myclass has been defined before.
>
> and
> test::~test()
> {
> map<string,myclass*>::iterator ii;
> for(ii=tests.begin();ii!=tests.end();++ii)
> {
> delete(ii->second);
> }
> tests.clear();
> }
> int main()
> {
> test my;
> myclass st;
> my.AddMyclass("new class",st);
> }
> But when the code exits from the main function, there was an error
> message saying that "Object reference not set to an instance of an
> object.".


Wow, that is quite cryptic a message.

> I think it is caused by the test's destructor function. But I don't
> know where is the problem.


When the destructor runs, it effectively calls

delete( &st );

which tries to deallocate memory that was not obtained by new(). That is a
BadIdea(tm), at the very least, it is undefined behavior. More important,
it may hint at a design problem. When using pointers, you need to consider
carefully ownership and lifetime. In this case, the test object claims
ownership of the pointees of all pointers stored in the map: after all, it
assumes the right to delete them. It would, therefore, be best if the
AddMyClass() method would new() the pointers. Otherwise, you have a
transfer of ownership.


Best

Kai-Uwe Bux
 
Reply With Quote
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      03-17-2007
David wrote:

[snip]
> Sorry I forget the function AddMyclass();
> void test::AddMyclass(const string &myname,const myclass &st)
> {
> map<string,myclass*>:;iterator ii;

^
That should be a ":", right? Also, ii is not used further down the code.

> myclass *newmyclass=NULL;
> newmyclass=new myclass(st);


That can be combined into:

myclass * newmyclass = new myclass ( st );

> tests[myname]=newmyclass;
> }


This is most definitely not the code that you use in your program. For one
thing, it does not compile. Please post the actual code that demonstrates
the problem. Make it a complete, but small program that others can just cut
and paste. You want to make it as easy as possible for others to help you.


Best

Kai-Uwe Bux


 
Reply With Quote
 
Adrian Hawryluk
Guest
Posts: n/a
 
      03-17-2007
David wrote:
> On Mar 17, 11:32 am, "Victor Bazarov" <(E-Mail Removed)> wrote:
>> David wrote:
>>> I try to use map container and delete the elements. but there are
>>> something wrong, please help me check it.


I'm sorry, what is wrong? Your code was not compilable. I tweaked it
to get it to work with empty default types and constructors. But for
all I know, it is not what you want. Here is what I did:

#include <map>
#include <string>

using namespace std;

class myclass {
};

class test{
protected:
map<string,myclass*> tests;

public:
test() {}
void AddMyclass(const string& myname,const myclass &st);
~test();
};

test::~test()
{
map<string,myclass*>::iterator ii;
for(ii=tests.begin();ii!=tests.end();++ii)
{
delete(ii->second);
}
tests.clear();
}

void test::AddMyclass(const string &myname,const myclass &st)
{
map<string,myclass*>::iterator ii;
myclass *newmyclass=NULL;
newmyclass=new myclass(st);
tests[myname]=newmyclass;
}

int main()
{
test my;
myclass st;
my.AddMyclass("new class",st);
}

Excuse the indentation, but I'm not going to bother fixing the minor
cosmetic problem.

So can you point out the problem? Or submit working code and point it
out there?


Adrian
--
__________________________________________________ ___________________
\/Adrian_Hawryluk BSc. - Specialties: UML, OOPD, Real-Time Systems\/
\ My newsgroup writings are licensed under the Creative Commons /
\ Attribution-Noncommercial-Share Alike 3.0 License /
\_____[http://creativecommons.org/licenses/...sa/3.0/]_____/
\/______[blog:__http://adrians-musings.blogspot.com/]______\/
 
Reply With Quote
 
Jim Langston
Guest
Posts: n/a
 
      03-17-2007
"David" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) ups.com...
> Hi all,
>
> I try to use map container and delete the elements. but there are
> something wrong, please help me check it.
>
> class test{
> protected:
> map<string,myclass*> tests;
>
> public:
> test();
> void AddMyclass(const string& myname,const myclass &st);
> ~test();
> };
>
> suppose myclass has been defined before.
>
> and
> test::~test()
> {
> map<string,myclass*>::iterator ii;
> for(ii=tests.begin();ii!=tests.end();++ii)
> {
> delete(ii->second);
> }
> tests.clear();
> }
> int main()
> {
> test my;
> myclass st;
> my.AddMyclass("new class",st);
> }
> But when the code exits from the main function, there was an error
> message saying that "Object reference not set to an instance of an
> object.".
>
> I think it is caused by the test's destructor function. But I don't
> know where is the problem. Please help me. Thanks


This is snippets of code I use that works.

typedef std::map<unsigned int, CEffect*> BeamEffectsType;

// ...

BeamEffectsType BeamEffects;

// ...

CEffect* Effect = new CEffect(ProjectileSpeed, Lifetime, Pos, Aim,
FireIndex, CEffect:articleStream);
BeamEffects.insert( std::make_pair< unsigned int, CEffect* >( Index,
Effect ) );

// ...

// Update ALL the -On-The-Fly- or Fired 'Beams' to NEW positions.
for ( BeamEffectsType::iterator it = BeamEffects.begin(); it !=
BeamEffects.end(); )
{
if ( !(*it).second->Update() )
{
delete (*it).second;
it = Client.BeamEffects.erase(it);
}
else
++it;
}

// ...

for ( BeamEffectsType::iterator it = BeamEffects.begin(); it !=
BeamEffects.end(); )
{
delete (*it).second;
++it;
}

Incidently, in this code
(*it).second;
is equivalent to
it->second;

It is just the way I prefer to do it


 
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
std::map::find() throws exception when map is empty? Matthias Hildebrand C++ 5 03-20-2012 06:09 AM
I can map all files (.*) to asp.net worker.How do I map NO FILE to asp.net worker? alex ASP .Net 1 02-04-2005 03:18 AM
searching keys in std::map using map::upper_bound Erik Arner C++ 0 11-02-2004 11:14 PM
map.insert(key,val) vs. map[key]=val ? Patrick Guio C++ 6 10-20-2004 01:54 PM
map that maps to iterators in the same map ? Vlad C++ 0 12-15-2003 08:29 PM



Advertisments