delete map elements

D

David

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
 
V

Victor Bazarov

David said:
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
 
D

David

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)));
...




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


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



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

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,
 
K

Kai-Uwe Bux

David said:
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
 
K

Kai-Uwe Bux

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
 
A

Adrian Hawryluk

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/by-nc-sa/3.0/]_____/
\/______[blog:__http://adrians-musings.blogspot.com/]______\/
 
J

Jim Langston

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

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

No members online now.

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,225
Latest member
Top Crypto Podcasts

Latest Threads

Top