473,386 Members | 1,790 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Clarification for std::vector and std::map

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.size()<<" : "<<v[0]<<endl;

v.erase(&v[0]);

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

cout<<"Vec size: "<<v.size()<<endl;

return 0;
}

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

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

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
Jul 19 '05 #1
5 6048
"Sir_Ciph3r" <Si********@nospam.com> wrote...
Can someone explain what is happening in the following code?
Undefined behaviour.
#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];
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".
cout<<"Vec size: "<<v.size()<<" : "<<v[0]<<endl;

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'.

cout<<"Map: "<<*m["TEST"]<<endl;
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.

cout<<"Vec size: "<<v.size()<<endl;

return 0;
}

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

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

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.
Is this code safe?


Absolutely not.

Victor
Jul 19 '05 #2
"Sir_Ciph3r" <Si********@nospam.com> wrote in message
news:ro********************************@4ax.com...
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.size()<<" : "<<v[0]<<endl;

v.erase(&v[0]);

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

cout<<"Vec size: "<<v.size()<<endl;

return 0;
}

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

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

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<int> v;
map<string, vector<int>::iterator> m;

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

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

v.erase(v.begin());

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

cout<<"Vec size: "<<v.size()<<endl;

return 0;
}

--
ES Kim

Jul 19 '05 #3


Sir_Ciph3r wrote:
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
Jul 19 '05 #4
On Wed, 30 Jul 2003 18:13:48 -0400, "Victor Bazarov"
<v.********@attAbi.com> wrote:

Thanks for the help guys, I am slowing learning.

With this advice ->

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();)
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
element\n"));
#endif
}
else
++IVec;
}
Jul 19 '05 #5
On Wed, 30 Jul 2003 18:13:48 -0400, "Victor Bazarov"
<v.********@attAbi.com> wrote:
"Sir_Ciph3r" <Si********@nospam.com> wrote...
Can someone explain what is happening in the following code?


Undefined behaviour.
#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];


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

Jul 19 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Woodster | last post by:
I have declared the following std::map<std::string, std::string> myMap; to pass myMap to functions should I be declaring functions as: void function(std::map<std::string, std::string>); ...
5
by: cppaddict | last post by:
Hi, I'm confused about what the comparison operator in a map template is: In particular, I want to know why something like the following doesn't work: bool pointCompare(POINT p1, POINT p2)...
44
by: jmoy | last post by:
I am a C programmer graduating to C++. As an exercise I wrote a program to count the number of times that different words occur in a text file. Though a hash table might have been a better choice,...
2
by: Serengeti | last post by:
Hello, in my class I have a map that translates strings to pointers to some member functions. The code goes like this: class F { typedef void (Function::*MathFuncPtr)(); std::map<std::string,...
5
by: Peter Jansson | last post by:
Hello, I have the following code: std::map<int,std::set<std::string> > k; k="1234567890"; k="2345678901"; //... std::set<std::string> myMethod(std::map<int,std::set<std::string> > k)...
2
by: Mike Lischke | last post by:
Hi group, Does anybody of you know a template that unites a vector and a hash map? What I'm after is a hash map that can also be accessed by index. I know that an associative container is not...
17
by: Michael Hopkins | last post by:
Hi all I want to create a std::vector that goes from 1 to n instead of 0 to n-1. The only change this will have is in loops and when the vector returns positions of elements etc. I am calling...
3
by: Dan Trowbridge | last post by:
Hi everyone, In my attempt to port code from VS 6.0 to VS.NET I had some code break along the way, mostly due to not adhereing closely to the C++ standard. This may be another instance but I...
13
by: kamaraj80 | last post by:
Hi I am using the std:: map as following. typedef struct _SeatRowCols { long nSeatRow; unsigned char ucSeatLetter; }SeatRowCols; typedef struct _NetData
2
by: digz | last post by:
Hi, I am trying to write a program which has two threads one of them write to a map , and the other one deletes entries based on a certain criterion.. first I cannot get the delete portion to...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.