473,473 Members | 1,844 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Pointer Dereferencing

Hello friends,

Recently I have begun exploring the features that the STL map
collection provides. While learning how it worked, I encountered a
result that confused me. Up until now, I had always been under the
impression that if I had a pointer variable, p which contained the
member "first", I could access this member variable either by:
(*p).first OR p->first . That is, in general I thought p->x was just
shorthand for (*p).x ?

The particular example I was working with was with printing an item
from a map:

map<string,intm ;
m.insert( make_pair( string( "test" ), false ) ) ;

map<string,int>::const_iterator it ;
for ( it = m.begin() ; it != m.end() ; it++ ) {
cout << it->first ; // THIS DOES NOT WORK
cout << (*it).first ; // This does work
}

Can anyone render an explanation to put my mind at ease?

Thanks in advance,

Mike

Nov 13 '06 #1
9 3176
Cyron wrote:
cout << it->first ; // THIS DOES NOT WORK
cout << (*it).first ; // This does work
Does "THIS DOES NOT WORK" mean that it doesn't compile? Some older
compilers (in particular, VC++ 6) had problems compiling operator-in a
class, so some older standard libraries don't provide it. It's supposed
to be there, though.

--

-- Pete
Roundhouse Consulting, Ltd. -- www.versatilecoding.com
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." For more information about this book, see
www.petebecker.com/tr1book.
Nov 13 '06 #2
In article <11**********************@m73g2000cwd.googlegroups .com>,
"Cyron" <md*******@yahoo.comwrote:
Hello friends,

Recently I have begun exploring the features that the STL map
collection provides. While learning how it worked, I encountered a
result that confused me. Up until now, I had always been under the
impression that if I had a pointer variable, p which contained the
member "first", I could access this member variable either by:
(*p).first OR p->first . That is, in general I thought p->x was just
shorthand for (*p).x ?

The particular example I was working with was with printing an item
from a map:

map<string,intm ;
m.insert( make_pair( string( "test" ), false ) ) ;

map<string,int>::const_iterator it ;
for ( it = m.begin() ; it != m.end() ; it++ ) {
cout << it->first ; // THIS DOES NOT WORK
cout << (*it).first ; // This does work
}

Can anyone render an explanation to put my mind at ease?
As I understand it, in very old compilers the -operator either was
not, or could not be, overloaded. So in that case they are not identical.

--
To send me email, put "sheltie" in the subject.
Nov 13 '06 #3
* Cyron:
>
Recently I have begun exploring the features that the STL map
collection provides. While learning how it worked, I encountered a
result that confused me. Up until now, I had always been under the
impression that if I had a pointer variable, p which contained the
member "first",
Nitpick: a pointer variable does not contain anything else than a
pointer value, but the pointed to object can contain members. Thus,
it's *p that contains the member "first".

I could access this member variable either by:
(*p).first OR p->first . That is, in general I thought p->x was just
shorthand for (*p).x ?
For built-in operations.

An iterator need not be a raw pointer. It can be an object that offers
pointer operations, and then operator-and operator* are two distinct
operations that might be implemented as just displaying respectively
"huh" and "bah" on std::cout... That said, ...

The particular example I was working with was with printing an item
from a map:

map<string,intm ;
m.insert( make_pair( string( "test" ), false ) ) ;

map<string,int>::const_iterator it ;
for ( it = m.begin() ; it != m.end() ; it++ ) {
cout << it->first ; // THIS DOES NOT WORK
cout << (*it).first ; // This does work
}
.... a standard library iterator is required to implement p->x to yield
the effect of (*p).x.

Can anyone render an explanation to put my mind at ease?
Your compiler's standard library implementation seems to be broken. But
then, you haven't defined what "does not work" means, and you haven't
shown a complete program (in particular which headers you have included,
and whether you're finally flushing the output stream) -- see the FAQ
about how to post a question about code that does not work. So it's
also possible that it's a simple coding error on your part, or just a
misunderstanding.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 13 '06 #4

Pete Becker wrote:
Cyron wrote:
cout << it->first ; // THIS DOES NOT WORK
cout << (*it).first ; // This does work

Does "THIS DOES NOT WORK" mean that it doesn't compile? Some older
compilers (in particular, VC++ 6) had problems compiling operator-in a
class, so some older standard libraries don't provide it. It's supposed
to be there, though.
Thanks for the response, Pete. I am indeed using an older compiler
(Borland C++ Builder 3). I often use this compiler from the console
(as in this case) and this is the error I receive when I try to
compile:

Borland C++ 5.3 for Win32 Copyright (c) 1993, 1998 Borland
International
map.cpp:
Error map.cpp 12: Pointer to structure required on left side of -or
->* in function main()
*** 1 errors in Compile ***

Nov 13 '06 #5
As I understand it, in very old compilers the -operator either was
not, or could not be, overloaded. So in that case they are not identical.
Thanks for your comment, Daniel. This is the first time I recall
encountering a problem where the -wouldn't dereference a pointer to a
struct/class object. I am, however, just beginning to use templates.
Do you think the problem is related to the fact that map is a template?
Someone else also suggested the compiler's age may playing a factor so
I will check into that too.

Nov 13 '06 #6
Nitpick: a pointer variable does not contain anything else than a
pointer value, but the pointed to object can contain members. Thus,
it's *p that contains the member "first".
Yes you are correct. Sorry for my unclear wording. So if *p contains
a member first,
p->first should be likewise valid? Or perhaps my problem lies in my
understanding of an iterator. Currently I'm under the impression that
when I call begin() on a map, I am receving the pointer to a structure
or class which contains an element named first (provided begin() !=
end() )
I could access this member variable either by:
(*p).first OR p->first . That is, in general I thought p->x was just
shorthand for (*p).x ?

For built-in operations.
Could you elaborate on this? Do you mean built in types? How does a
map iterator differ from a "built-in operation"?
An iterator need not be a raw pointer. It can be an object that
offers
pointer operations, and then operator-and operator* are two distinct
operations that might be implemented as just displaying respectively
"huh" and "bah" on std::cout... That said, ...
Ahh, this answered the first question I had. So you are saying that
the iterator being returned is possibly not a pointer at all. In this
case I would expect (*it).first and it->first to result in errors,
since both attempt to dereference the variable, it, as if it were a
pointer? Or do you mean that both the unary * and -operators have
been re-defined so that they have nothing to do with pointers? If this
last scenario is the case, what meaning would (*it).first have?
The particular example I was working with was with printing an item
from a map:

map<string,intm ;
m.insert( make_pair( string( "test" ), false ) ) ;

map<string,int>::const_iterator it ;
for ( it = m.begin() ; it != m.end() ; it++ ) {
cout << it->first ; // THIS DOES NOT WORK
cout << (*it).first ; // This does work
}

... a standard library iterator is required to implement p->x to yield
the effect of (*p).x.
OK, this is what I was hoping and epecting to observe. Others
mentioned that my compiler may be too old so I will try some newer
compilers too.
Can anyone render an explanation to put my mind at ease?

Your compiler's standard library implementation seems to be broken. But
then, you haven't defined what "does not work" means, and you haven't
shown a complete program (in particular which headers you have included,
and whether you're finally flushing the output stream) -- see the FAQ
about how to post a question about code that does not work. So it's
also possible that it's a simple coding error on your part, or just a
misunderstanding.
Yes, forgive me for the lack of information and the ambiguity regarding
the program details. Below is the exact program I am using. The
following contents are stored in map.cpp:
#include <string>
#include <map>
#include <iostream>

using namespace std ;
int main() {
map<string,inttest ;
test.insert( make_pair( string( "test" ), 5 ) ) ;
map<string, int>::iterator it;

for ( it = test.begin() ; it != test.end() ; ++it ) {
std::cout << it->first ; // Statement in question
}
return( 0 ) ;
}
If the line marked as "Statement in question" is as shown above an
attempt to compile (bcc32 map.cpp) results in:

Borland C++ 5.3 for Win32 Copyright (c) 1993, 1998 Borland
International
map.cpp:
Error map.cpp 12: Pointer to structure required on left side of -or
->* in function main()
*** 1 errors in Compile ***

At first glance I would normally think this error message indicates
that "it" is not a pointer. I looked around online to find a solution
and saw someone using *it so tried it instead of the -and voila! it
worked. That is, if i replace the "Statement in question" in the above
program with:

std::cout << (*it).first ; // Statement in question

The program compiles with no errors and functions as expected.

This led me to believe that "it" was indeed a pointer, but for some
reason * and not -were working with it.

Nov 13 '06 #7
* Cyron:
>Nitpick: a pointer variable does not contain anything else than a
pointer value, but the pointed to object can contain members. Thus,
it's *p that contains the member "first".

Yes you are correct. Sorry for my unclear wording. So if *p contains
a member first,
p->first should be likewise valid? Or perhaps my problem lies in my
understanding of an iterator. Currently I'm under the impression that
when I call begin() on a map, I am receving the pointer to a structure
or class which contains an element named first (provided begin() !=
end() )
Nope, it /can't/ be a pointer because a map cannot be a contigous
structure (because of performance requirements of its operations), and
you're incrementing the iterator to go from item to item.

>>I could access this member variable either by:
(*p).first OR p->first . That is, in general I thought p->x was just
shorthand for (*p).x ?
For built-in operations.

Could you elaborate on this? Do you mean built in types? How does a
map iterator differ from a "built-in operation"?
Given (off the cuff, not tested)

struct Value
{
int x;
};

Value const v = { 12345 };

struct Accessor
{
Value const* operator->() const { return &v; }
Value const& operator*() const { return v; }
};

int main()
{
Accessor const a;

std::cout << (*a).x << std::endl;
std::cout << a->x << std::endl;
}

the first output statement is (conceptually) translated to

Value const& _r = a.operator*();
std::cout _r.x << std::endl;

and the second output statement is translated to

Value const* _p = a.operator->();
std::cout << _p->x << std::endl;

which if the Value class offers its own operator-will in turn result
in a call to /that/ operator->, and so on, but since the Value class
doesn't, the -is here the built-in pointer operation, this ends up as

Value const* _p = a.operator->();
std::cout << (*_p).x << std::endl;

An iterator need not be a raw pointer. It can be an object that
offers
>pointer operations, and then operator-and operator* are two distinct
operations that might be implemented as just displaying respectively
"huh" and "bah" on std::cout... That said, ...

Ahh, this answered the first question I had. So you are saying that
the iterator being returned is possibly not a pointer at all. In this
case I would expect (*it).first and it->first to result in errors,
since both attempt to dereference the variable, it, as if it were a
pointer? Or do you mean that both the unary * and -operators have
been re-defined so that they have nothing to do with pointers?
Yes, essentially.

If this
last scenario is the case, what meaning would (*it).first have?
'*it' produces a C++ reference, an alias for some object.

>> The particular example I was working with was with printing an item
from a map:

map<string,intm ;
m.insert( make_pair( string( "test" ), false ) ) ;

map<string,int>::const_iterator it ;
for ( it = m.begin() ; it != m.end() ; it++ ) {
cout << it->first ; // THIS DOES NOT WORK
cout << (*it).first ; // This does work
}
... a standard library iterator is required to implement p->x to yield
the effect of (*p).x.

OK, this is what I was hoping and epecting to observe. Others
mentioned that my compiler may be too old so I will try some newer
compilers too.
Good idea.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 13 '06 #8
Cyron:
That is, in general I thought p->x was just shorthand for (*p).x ?

And you were correct to think that, because it is.

The particular example I was working with was with printing an item
from a map:

map<string,intm ;
m.insert( make_pair( string( "test" ), false ) ) ;

You do realise that that invocation of "make_pair" will yield a pair
<string,booland not a pair<string,int>, right?

Can anyone render an explanation to put my mind at ease?

As others have pointed out, you're using a K++ compiler. Get a C++ one.

--

Frederick Gotham
Nov 13 '06 #9
If this
last scenario is the case, what meaning would (*it).first have?

'*it' produces a C++ reference, an alias for some object.
Thank You for your explanations and example, Alf. I believe I now have
an understanding of the situation.

Mike

Nov 13 '06 #10

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

Similar topics

51
by: BigMan | last post by:
Does the C++ standard define what should happen in case of NULL pointer dereferencing. If not, does it say that it is illegal? Where, if so, does it say it?
110
by: Mr A | last post by:
Hi! I've been thinking about passing parameteras using references instead of pointers in order to emphasize that the parameter must be an object. Exemple: void func(Objec& object); //object...
3
by: Bruno van Dooren | last post by:
Hi All, i have some (3) different weird pointer problems that have me stumped. i suspect that the compiler behavior is correct because gcc shows the same results. ...
4
by: Pushkar Pradhan | last post by:
I have some functions which take as i/p a buffer (it can be float, char, or 16 bit, int etc.). The result is another o/p buffer, its type is also flexible (it could be a float, char etc.). I try...
4
by: Kobu | last post by:
I've read the FAQ and several posts on multidimensional arrays and how their names decay to pointer to arrays (not pointer to pointers). If this is so, why does the following code fragment...
204
by: Alexei A. Frounze | last post by:
Hi all, I have a question regarding the gcc behavior (gcc version 3.3.4). On the following test program it emits a warning: #include <stdio.h> int aInt2 = {0,1,2,4,9,16}; int aInt3 =...
13
by: aegis | last post by:
The following was mentioned by Eric Sosman from http://groups.google.com/group/comp.lang.c/msg/b696b28f59b9dac4?dmode=source "The alignment requirement for any type T must be a divisor of...
2
by: toton | last post by:
Hi, This is continuation of topic pointer & reference doubt. http://groups.google.com/group/comp.lang.c++/browse_thread/thread/df84ce6b9af561f9/76304d7d77f6ccca?lnk=raot#76304d7d77f6ccca But I...
20
by: prashant.khade1623 | last post by:
I am not getting the exact idea. Can you please explain me with an example. Thanks
3
by: tfelb | last post by:
Hi group! I have here five different declarations but I have some problems to understand this concept. I know there are more examples if I would use parentheses but I think the following ones...
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
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

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.