C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Clarification for std::vector and std::map

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++)
View previous topic :: View next topic  
Author Message
Jonathan Mcdougall
Guest





PostPosted: Wed Jul 30, 2003 9:00 am    Post subject: Re: Clarification for std::vector and std::map Reply with quote



On Wed, 30 Jul 2003 18:13:48 -0400, "Victor Bazarov"
<v.Abazarov (AT) attAbi (DOT) com> wrote:

Quote:
"Sir_Ciph3r" <Sir_Ciph3r (AT) nospam (DOT) com> wrote...
Can someone explain what is happening in the following code?

Undefined behaviour.

#include <iostream
#include #include
using namespace std;

int main()
{
vector map<char*,int*> m;

v.push_back(99);
m["TEST"]=&v[0];

You're saving a pointer to an object that may vanish into thin
air at any point and the map won't know about it. That's called
"asking for trouble".

I was just wondering if

map<char*, int> m;

m["TEST"] = 4;
m["TEST"] = 6;

is guaranteed to work, knowing that "TEST" is a pointer to a c-style
string. To me, it seems that a compiler is allowed to have two
different "TEST" strings and to map the values to the pointer address,
no?


Jonathan


Back to top
Sir_Ciph3r
Guest





PostPosted: Wed Jul 30, 2003 10:03 pm    Post subject: Clarification for std::vector and std::map Reply with quote



Can someone explain what is happening in the following code?

#include <iostream>
#include <vector>
#include <map>

using namespace std;

int main()
{
vector<int> v;
map<char*,int*> m;

v.push_back(99);
m["TEST"]=&v[0];

cout<<"Vec size: "<
v.erase(&v[0]);

cout<<"Map: "<<*m["TEST"]<
cout<<"Vec size: "<
return 0;
}

I don't understand why I am getting "99" from this line of code

cout<<"Map: "<<*m["TEST"]<
I erased the vector element and the map only contained the address to
that vector element...yet I am still getting the value I pushed_back.
What is happening behind the scenes? Is this code safe?

Any help would be appreciated


Back to top
Victor Bazarov
Guest





PostPosted: Wed Jul 30, 2003 10:13 pm    Post subject: Re: Clarification for std::vector and std::map Reply with quote



"Sir_Ciph3r" <Sir_Ciph3r (AT) nospam (DOT) com> wrote...
Quote:
Can someone explain what is happening in the following code?

Undefined behaviour.

Quote:
#include <iostream
#include #include
using namespace std;

int main()
{
vector map<char*,int*> m;

v.push_back(99);
m["TEST"]=&v[0];

You're saving a pointer to an object that may vanish into thin
air at any point and the map won't know about it. That's called
"asking for trouble".

Quote:
cout<<"Vec size: "<
v.erase(&v[0]);

There is no 'erase' member that takes a pointer to int. If your
implementation _happens_ to have vector::iterator the same as
a pointer to the contained type, it doesn't mean it will work
on any other computers/compilers/platforms. You have to pass
an iterator to 'erase'.

Quote:

cout<<"Map: "<<*m["TEST"]<

After the 'erase' (which probably worked by some weird chance)
you're trying to dereference a pointer that doesn't exist any
longer. The behaviour is undefined. You get your 99, but you
could as well get flying nasal demons.

Quote:

cout<<"Vec size: "<
return 0;
}

I don't understand why I am getting "99" from this line of code

cout<<"Map: "<<*m["TEST"]<
I erased the vector element and the map only contained the address to
that vector element...yet I am still getting the value I pushed_back.
What is happening behind the scenes?

Impossible to say. Your code causes undefined behaviour.

Quote:
Is this code safe?

Absolutely not.

Victor



Back to top
ES Kim
Guest





PostPosted: Wed Jul 30, 2003 10:42 pm    Post subject: Re: Clarification for std::vector and std::map Reply with quote

"Sir_Ciph3r" <Sir_Ciph3r (AT) nospam (DOT) com> wrote

Quote:
Can someone explain what is happening in the following code?

#include <iostream
#include #include
using namespace std;

int main()
{
vector map<char*,int*> m;

v.push_back(99);
m["TEST"]=&v[0];

cout<<"Vec size: "<
v.erase(&v[0]);

cout<<"Map: "<<*m["TEST"]<
cout<<"Vec size: "<
return 0;
}

I don't understand why I am getting "99" from this line of code

cout<<"Map: "<<*m["TEST"]<
I erased the vector element and the map only contained the address to
that vector element...yet I am still getting the value I pushed_back.
What is happening behind the scenes? Is this code safe?

Any help would be appreciated



A container of raw pointers is usually not a good idea.
Use string and iterator instead of char* and int*.

int main()
{
vector map<string, vector m;

v.push_back(99);
m["TEST"]=v.begin();

cout<<"Vec size: "< cout<<"Map: "<<*m["TEST"]<
v.erase(v.begin());

// cout<<"Map: "<<*m["TEST"]< // v.erase() invalidates m["TEST"]

cout<<"Vec size: "<
return 0;
}

--
ES Kim




Back to top
Default User
Guest





PostPosted: Wed Jul 30, 2003 11:02 pm    Post subject: Re: Clarification for std::vector and std::map Reply with quote



Sir_Ciph3r wrote:

Quote:
I erased the vector element and the map only contained the address to
that vector element...yet I am still getting the value I pushed_back.
What is happening behind the scenes? Is this code safe?


You did all kinds of undefined behavior. Iterators and pointers into
vectors are invalidated as soon as you do any kind of operation on the
vector that make cause it to resize memory. Erase() certainly could have
done that. What probably happened with that the vector saw that you were
erasing the last element, so it just backed its valid end pointer by
one, and decreased the size so that the element you are pointing to will
be overwritten the next time.

What are you trying to accomplish?




Brian Rodenborn

Back to top
Sir_Ciph3r
Guest





PostPosted: Thu Jul 31, 2003 12:41 am    Post subject: Re: Clarification for std::vector and std::map Reply with quote

On Wed, 30 Jul 2003 18:13:48 -0400, "Victor Bazarov"
<v.Abazarov (AT) attAbi (DOT) com> wrote:

Thanks for the help guys, I am slowing learning.

With this advice ->

Quote:

There is no 'erase' member that takes a pointer to int. If your
implementation _happens_ to have vector::iterator the same as
a pointer to the contained type, it doesn't mean it will work
on any other computers/compilers/platforms. You have to pass
an iterator to 'erase'.



Would this be a safe way to erase an element from a vector?

std::vector<CWindowKeeperWindow*>::iterator IVec;

// for(UINT i=0;i<uiSize;i++)
for(IVec=m_vecInstalledTimers.begin();
IVec!=m_vecInstalledTimers.end()Wink
if((*IVec)->get_window_id()==hTreeItem)
{
//
m_vecInstalledTimers.erase(&m_vecInstalledTimers[i]);
IVec=m_vecInstalledTimers.erase(IVec);

#ifdef __CWINDOWKEEPER_DEBUG__
ConPrintf(_T("OnDeleteWindow() - erased timer
elementn"));
#endif
}
else
++IVec;
}

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.