Pointer to STL element address?

M

Michael

Hi all,

In the following STL insertion, how do I maintain a pointer pointing
to the address of that element being inserted?

Thanks!

my_list.push_back(my_element);

my_map[key]=my_element;
 
M

Michael

Michael said:
In the following STL insertion, how do I maintain a pointer pointing
to the address of that element being inserted?
http://www.cplusplus.com/reference/stl/

my_list.push_back(my_element);

std::list said:
my_map[key]=my_element;

std::map<YourKeyType,YourElementType>::iterator pointer=my_map.find(key);

Can this iterator be used as a normal C++ pointer?

my_map.find actually wastes some time.

Is there a way, when my_map inserts the element, I can get its address
as a pointer, instead of doing a "find" after insertion?
 
P

Pascal J. Bourguignon

Michael said:
Michael said:
In the following STL insertion, how do I maintain a pointer pointing
to the address of that element being inserted?
http://www.cplusplus.com/reference/stl/

my_list.push_back(my_element);

std::list said:
my_map[key]=my_element;

std::map<YourKeyType,YourElementType>::iterator pointer=my_map.find(key);

Can this iterator be used as a normal C++ pointer?

I don't know. What does http://www.cplusplus.com/reference/std/iterator/ say?
my_map.find actually wastes some time.

Is there a way, when my_map inserts the element, I can get its address
as a pointer, instead of doing a "find" after insertion?

I don't know. Isn't there a method that would insert an new pair and
return an interator listed in http://www.cplusplus.com/reference/stl/map/ ?


You don't believe I'll be doing your reading, do you?
 
M

Michael

Michael said:
In the following STL insertion, how do I maintain a pointer pointing
to the address of that element being inserted?
http://www.cplusplus.com/reference/stl/
my_list.push_back(my_element);
std::list<YourElementType>::iterator pointer=my_list.end()-1;
my_map[key]=my_element;
std::map<YourKeyType,YourElementType>::iterator pointer=my_map.find(key);
Can this iterator be used as a normal C++ pointer?

I don't know.  What doeshttp://www.cplusplus.com/reference/std/iterator/say?
my_map.find actually wastes some time.
Is there a way, when my_map inserts the element, I can get its address
as a pointer, instead of doing a "find" after insertion?

I don't know.  Isn't there a method that would insert an new pair and
return an interator listed inhttp://www.cplusplus.com/reference/stl/map/?

You don't believe I'll be doing  your reading, do you?

Of course I am very familiar with those pages already, before I asked
the question.

My problem is that actually I have maps of lists, I want to be able to
keep track of the address of the very element that has been inserted
last...
 
M

Michael

Michael said:
In the following STL insertion, how do I maintain a pointer pointing
to the address of that element being inserted?
http://www.cplusplus.com/reference/stl/
my_list.push_back(my_element);
std::list<YourElementType>::iterator pointer=my_list.end()-1;
my_map[key]=my_element;
std::map<YourKeyType,YourElementType>::iterator pointer=my_map.find(key);
Can this iterator be used as a normal C++ pointer?

I don't know.  What doeshttp://www.cplusplus.com/reference/std/iterator/say?
my_map.find actually wastes some time.
Is there a way, when my_map inserts the element, I can get its address
as a pointer, instead of doing a "find" after insertion?

I don't know.  Isn't there a method that would insert an new pair and
return an interator listed inhttp://www.cplusplus.com/reference/stl/map/?

You don't believe I'll be doing  your reading, do you?

If the List was already inserted into the Map:

---------------

my_list.push_back(my_element);

std::list<YourElementType>::iterator pointer=my_list.end()-1;

my_map[key]=my_list;
 
P

Pascal J. Bourguignon

Michael said:
Michael said:
On May 25, 8:33 am, (e-mail address removed) (Pascal J. Bourguignon)
wrote:
In the following STL insertion, how do I maintain a pointer pointing
to the address of that element being inserted?
my_list.push_back(my_element);

std::list<YourElementType>::iterator pointer=my_list.end()-1;
my_map[key]=my_element;

std::map<YourKeyType,YourElementType>::iterator pointer=my_map.find(key);
Can this iterator be used as a normal C++ pointer?

I don't know.  What doeshttp://www.cplusplus.com/reference/std/iterator/say?
my_map.find actually wastes some time.
Is there a way, when my_map inserts the element, I can get its address
as a pointer, instead of doing a "find" after insertion?

I don't know.  Isn't there a method that would insert an new pair and
return an interator listed inhttp://www.cplusplus.com/reference/stl/map/?

You don't believe I'll be doing  your reading, do you?

If the List was already inserted into the Map:

---------------

my_list.push_back(my_element);

std::list<YourElementType>::iterator pointer=my_list.end()-1;

my_map[key]=my_list;

Well, not really. In general iterators are rather volatile: a lot of
operations render them invalid.

The problem is that a lot of operations with the STL actually do COPY
the objects, so called "value" semantic.

If you want to keep a pointer to the last 'object' you put in a list,
(be it a true C++ pointer, or a smart pointer of some kind), I would
advise to only put pointers (or smart pointers) in your lists.

YourElementType* element=makeSomeElement();
YourElementType* lastInserted=0;
std::list<YourElementType*> my_list;
my_list.push_back(lastInserted=element);

std::map<YouKeyType,std::list<YourElementType*> > my_map;
my_map[key]=my_list;

// Here, lastInserted is still valid and still point to the *element.
 
M

Michael

Michael said:
On May 25, 8:33 am, (e-mail address removed) (Pascal J. Bourguignon)
wrote:
In the following STL insertion, how do I maintain a pointer pointing
to the address of that element being inserted?
http://www.cplusplus.com/reference/stl/
my_list.push_back(my_element);
std::list<YourElementType>::iterator pointer=my_list.end()-1;
my_map[key]=my_element;
std::map<YourKeyType,YourElementType>::iterator pointer=my_map.find(key);
Can this iterator be used as a normal C++ pointer?
I don't know.  What doeshttp://www.cplusplus.com/reference/std/iterator/say?
my_map.find actually wastes some time.
Is there a way, when my_map inserts the element, I can get its address
as a pointer, instead of doing a "find" after insertion?
I don't know.  Isn't there a method that would insert an new pair and
return an interator listed inhttp://www.cplusplus.com/reference/stl/map/?
You don't believe I'll be doing  your reading, do you?
If the List was already inserted into the Map:
---------------
my_list.push_back(my_element);

std::list<YourElementType>::iterator pointer=my_list.end()-1;
my_map[key]=my_list;
---------------

Will this pointer be pointing to the correct location, i.e. the
address of my_element, even after being nested within the Map?

Well, not really.  In general iterators are rather volatile: a lot of
operations render them invalid.

The problem is that a lot of operations with the STL actually do COPY
the objects, so called "value" semantic.

If you want to keep a pointer to the last 'object' you put in a list,
(be it a true C++ pointer, or a smart pointer of some kind), I would
advise to only put pointers (or smart pointers) in your lists.

YourElementType* element=makeSomeElement();
YourElementType* lastInserted=0;
std::list<YourElementType*> my_list;
my_list.push_back(lastInserted=element);

std::map<YouKeyType,std::list<YourElementType*> > my_map;
my_map[key]=my_list;

// Here, lastInserted is still valid and still point to the *element.

Sounds good.
But let's say my element is only one real number, does adding all
these pointers waste a lot of memory, and I have a large set of
data ...
 
M

Michael

Michael said:
On May 25, 8:33 am, (e-mail address removed) (Pascal J. Bourguignon)
wrote:
In the following STL insertion, how do I maintain a pointer pointing
to the address of that element being inserted?
http://www.cplusplus.com/reference/stl/
my_list.push_back(my_element);
std::list<YourElementType>::iterator pointer=my_list.end()-1;
my_map[key]=my_element;
std::map<YourKeyType,YourElementType>::iterator pointer=my_map.find(key);
Can this iterator be used as a normal C++ pointer?
I don't know.  What doeshttp://www.cplusplus.com/reference/std/iterator/say?
my_map.find actually wastes some time.
Is there a way, when my_map inserts the element, I can get its address
as a pointer, instead of doing a "find" after insertion?
I don't know.  Isn't there a method that would insert an new pair and
return an interator listed inhttp://www.cplusplus.com/reference/stl/map/?
You don't believe I'll be doing  your reading, do you?
If the List was already inserted into the Map:
---------------
my_list.push_back(my_element);

std::list<YourElementType>::iterator pointer=my_list.end()-1;
my_map[key]=my_list;
---------------

Will this pointer be pointing to the correct location, i.e. the
address of my_element, even after being nested within the Map?

Well, not really.  In general iterators are rather volatile: a lot of
operations render them invalid.

The problem is that a lot of operations with the STL actually do COPY
the objects, so called "value" semantic.

If you want to keep a pointer to the last 'object' you put in a list,
(be it a true C++ pointer, or a smart pointer of some kind), I would
advise to only put pointers (or smart pointers) in your lists.

YourElementType* element=makeSomeElement();
YourElementType* lastInserted=0;
std::list<YourElementType*> my_list;
my_list.push_back(lastInserted=element);

std::map<YouKeyType,std::list<YourElementType*> > my_map;
my_map[key]=my_list;

// Here, lastInserted is still valid and still point to the *element.

Okay! How do I deallocate the allocated memory after using the map and
list?
 
M

Michael

Michael said:
On May 25, 8:33 am, (e-mail address removed) (Pascal J. Bourguignon)
wrote:
In the following STL insertion, how do I maintain a pointer pointing
to the address of that element being inserted?
http://www.cplusplus.com/reference/stl/
my_list.push_back(my_element);
std::list<YourElementType>::iterator pointer=my_list.end()-1;
my_map[key]=my_element;
std::map<YourKeyType,YourElementType>::iterator pointer=my_map.find(key);
Can this iterator be used as a normal C++ pointer?
I don't know.  What doeshttp://www.cplusplus.com/reference/std/iterator/say?
my_map.find actually wastes some time.
Is there a way, when my_map inserts the element, I can get its address
as a pointer, instead of doing a "find" after insertion?
I don't know.  Isn't there a method that would insert an new pair and
return an interator listed inhttp://www.cplusplus.com/reference/stl/map/?
You don't believe I'll be doing  your reading, do you?
If the List was already inserted into the Map:
---------------
my_list.push_back(my_element);

std::list<YourElementType>::iterator pointer=my_list.end()-1;
my_map[key]=my_list;
---------------

Will this pointer be pointing to the correct location, i.e. the
address of my_element, even after being nested within the Map?

Well, not really.  In general iterators are rather volatile: a lot of
operations render them invalid.

The problem is that a lot of operations with the STL actually do COPY
the objects, so called "value" semantic.

If you want to keep a pointer to the last 'object' you put in a list,
(be it a true C++ pointer, or a smart pointer of some kind), I would
advise to only put pointers (or smart pointers) in your lists.

YourElementType* element=makeSomeElement();
YourElementType* lastInserted=0;
std::list<YourElementType*> my_list;
my_list.push_back(lastInserted=element);

std::map<YouKeyType,std::list<YourElementType*> > my_map;
my_map[key]=my_list;

// Here, lastInserted is still valid and still point to the *element.

It's really boring to traverse all the maps and the nested lists to
deallocate all the allocated memory...

(I don't have BOOST installed so I don't know how to use that one at
this stage).
 
M

Michael

Michael said:
On May 25, 8:33 am, (e-mail address removed) (Pascal J. Bourguignon)
wrote:
In the following STL insertion, how do I maintain a pointer pointing
to the address of that element being inserted?
http://www.cplusplus.com/reference/stl/
my_list.push_back(my_element);
std::list<YourElementType>::iterator pointer=my_list.end()-1;
my_map[key]=my_element;
std::map<YourKeyType,YourElementType>::iterator pointer=my_map.find(key);
Can this iterator be used as a normal C++ pointer?
I don't know.  What doeshttp://www.cplusplus.com/reference/std/iterator/say?
my_map.find actually wastes some time.
Is there a way, when my_map inserts the element, I can get its address
as a pointer, instead of doing a "find" after insertion?
I don't know.  Isn't there a method that would insert an new pair and
return an interator listed inhttp://www.cplusplus.com/reference/stl/map/?
You don't believe I'll be doing  your reading, do you?
If the List was already inserted into the Map:
---------------
my_list.push_back(my_element);

std::list<YourElementType>::iterator pointer=my_list.end()-1;
my_map[key]=my_list;
---------------

Will this pointer be pointing to the correct location, i.e. the
address of my_element, even after being nested within the Map?

Well, not really.  In general iterators are rather volatile: a lot of
operations render them invalid.

The problem is that a lot of operations with the STL actually do COPY
the objects, so called "value" semantic.

If you want to keep a pointer to the last 'object' you put in a list,
(be it a true C++ pointer, or a smart pointer of some kind), I would
advise to only put pointers (or smart pointers) in your lists.

YourElementType* element=makeSomeElement();
YourElementType* lastInserted=0;
std::list<YourElementType*> my_list;
my_list.push_back(lastInserted=element);

std::map<YouKeyType,std::list<YourElementType*> > my_map;
my_map[key]=my_list;

// Here, lastInserted is still valid and still point to the *element.

Too bad, I realize it doesn't work.

Because I still want to keep track of the iterator to that element in
the list, because I want to do removal, etc. on that element. I have
to keep track of the iterator. But we know that iterator is really
volatile, and can change after nesting lists into maps and so on and
so forth...
 
J

James Kanze

Michael said:
In the following STL insertion, how do I maintain a pointer pointing
to the address of that element being inserted?
http://www.cplusplus.com/reference/stl/
my_list.push_back(my_element);
std::list<YourElementType>::iterator pointer=my_list.end()-1;
my_map[key]=my_element;
std::map<YourKeyType,YourElementType>::iterator pointer=my_map.find(key);
Can this iterator be used as a normal C++ pointer?

Not in all cases. It can be used as a normal C++ pointer in
certain cases.
my_map.find actually wastes some time.
Is there a way, when my_map inserts the element, I can get its
address as a pointer, instead of doing a "find" after
insertion?

Use map<>::insert.
 
J

James Kanze

Michael said:
On May 25, 8:49 am, (e-mail address removed) (Pascal J. Bourguignon)
wrote:
If the List was already inserted into the Map:

No. On the other hand, if you do:

my_map[ key ].push_back( my_element ) ;
std::list<...>::iterator pointer = my_map[ key ].end() - 1 ;

you're safe. (Note that std::list<>::iterator is not a random
access iterator, so you can't add and subtract on it.) Use a
reference to the list if you're worried about performance:

my_list<...>& list = my_map[ key ] ;
list.push_back( my_element ) ;
std::list<...>::iterator pointer = list.end() ;
-- pointer ;

But in practice, the time necessary to insert an element in the
list will be large enough that the extra look-up won't matter.
Well, not really. In general iterators are rather volatile: a
lot of operations render them invalid.

That's not really true for node based containers, like list and
map. But you're right to warn about it---I can easily imagine
changing std::list to std::vector at some later time, for
performance reasons, and watching things break.
The problem is that a lot of operations with the STL actually
do COPY the objects, so called "value" semantic.
If you want to keep a pointer to the last 'object' you put in
a list, (be it a true C++ pointer, or a smart pointer of some
kind), I would advise to only put pointers (or smart pointers)
in your lists.

Generally, if it makes any sense to have a pointer to the
object, the object has identity, and can't be copied anyway. So
you have to use a container of pointers. Still, there are
exceptions, and I've used pointers to objects in an std::map on
a few rare occasions.
 
P

Pascal J. Bourguignon

Mateusz Loskot said:
But why you need to access these elements by pointers at all?
You shouldn't need that. You have all necessary tools in your hands to
access the elements in every usable manner (read, write).

Perhaps you should redesign your solution.

Indeed, you can always do my_map[key].back() to get the last element.
Or keep a copy of the value somewhere.
 
R

Richard Herring

In message
But we know that iterator is really
volatile, and can change after nesting lists into maps and so on and
so forth...

Do we?

It might be very much to your advantage to find out which operations on
lists and maps really do invalidate iterators into them, and which
don't, and which iterators they invalidate.
 

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,982
Messages
2,570,186
Members
46,740
Latest member
JudsonFrie

Latest Threads

Top