473,883 Members | 1,602 Online
Bytes | Software Development & Data Engineering Community
+ 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_iterato r 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 3213
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************ **********@m73g 2000cwd.googleg roups.com>,
"Cyron" <md*******@yaho o.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_iterato r 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_iterato r 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
misunderstandin g.

--
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_iterato r 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
misunderstandin g.
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,intt est ;
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_iterato r 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,boola nd 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
3214
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
10007
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 must be an object instead of
3
2367
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. ---------------------------------------------- //example 1: typedef int t_Array; int main(int argc, char* argv)
4
16171
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 to pass both as "void *buf" so that it can accept any data type. But since I access the buffer and try to assign its elements to another I get compile errors (I have pasted at the end). Now my question is how can I pass the i/p and o/p buffers...
4
2706
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 compiler and run correctly?: #include <stdio.h> int main()
204
13167
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 = {0,1,2,4,9};
13
3008
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 sizeof(T). (Proof: In `T array;' both `array' and `array' must be correctly aligned.) Since `sizeof(unsigned char)' is divisible only by one and since one is a divisor of every type's size, every type is suitably aligned for `unsigned char'."
2
2853
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 think it is better to have a new topic rather than continuing on old one. As now I am sure pointer to reference and reference to pointer are freely convertable, the potential danger lies in the first one. Pointer may be NULL, but reference should...
20
3243
by: prashant.khade1623 | last post by:
I am not getting the exact idea. Can you please explain me with an example. Thanks
3
7413
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 are common. What I've learned.. int myArray = { 0, 1, 2 }; int *ptr = myArray;
0
9933
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9781
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
11118
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10407
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9564
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5791
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 last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4606
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
4209
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3230
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 can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.