# Simple Question--char *

1 view

### dave

Feb 7, 2006, 6:20:51 AM2/7/06
to
I think I understand that

char * ptr = "string"

declares a pointer initialized to a possibly modifiable constant string.

So, I thought I knew what I would see when I ran the following:

char * char_ptr = "stringthingy";
int integer = 1234;
int * int_ptr = &integer;
...
cout << "Size of char_ptr is " << sizeof(char_ptr) << "\n\n";
cout << "*char_ptr = " << *char_ptr << "\n";
cout << "char_ptr = " << char_ptr << "\n";

cout << "Size of int_ptr is " << sizeof(int_ptr) << "\n\n";
cout << "*int_ptr = " << *int_ptr << "\n";
cout << "int_ptr = " << int_ptr << "\n";

But, I was surprised to see this result:

Size of char_ptr is 4
*char_ptr = s
char_ptr = stringthingy

Size of int_ptr is 4
*int_ptr = 1234
int_ptr = 0x804e03c

Why is the non-deferenced char_ptr not an address in memory?? The
non-dereferenced int_ptr result is. Is "<<" overloaded to dereference
a char ptr? If so, why not for an int ptr? If it is overloaded, why
does "<< char_ptr" produce a different result from "<< *char_ptr"?

I am a bit confused.

TIA,

~Dave~

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

### Kurt Stege

Feb 7, 2006, 9:15:49 AM2/7/06
to
dave wrote:
> I think I understand ...

I think you understand quite much about pointers and C++.
Examples and details to questions snipped...

> Is "<<" overloaded to dereference a char ptr?

Yes. In a way that the pointer is interpreted as an
old fashioned pointer to a zero terminated string.
The reason is to allow things like

std::cout << "Hello World!\n";

In this context you expect to see the string, and
not the address of the string as output.

> If so, why not for an int ptr?

The reason for char ptr does not work for int ptr.

> If it is overloaded, why
> does "<< char_ptr" produce a different result from "<< *char_ptr"?

Because << is overloaded, not *. *char_ptr is of type char.
And << called with a char outputs exactly that one character,
as expected by std::cout << '\n';

It would be possible to overload << to take the address of the
given char and output the following characters in memory as well,
but this is far from useful and nobody has done it.

> I am a bit confused.

That is good. A sign for real understanding.

Best regards,
Kurt.

### Valentin Samko

Feb 8, 2006, 4:54:39 AM2/8/06
to
dave wrote:
> char * ptr = "string"
> declares a pointer initialized to a possibly modifiable constant string.
It's not modifiable. ptr is modifiable, the string it points to - no.

> So, I thought I knew what I would see when I ran the following:
> char * char_ptr = "stringthingy";
> int integer = 1234;
> int * int_ptr = &integer;

> cout << "*int_ptr = " << *int_ptr << "\n";

And here you get an undefined behaviour, as you are dereferencing an int ptr which points
to a storage area which was not initialised as an integer.

> Why is the non-deferenced char_ptr not an address in memory?? The
> non-dereferenced int_ptr result is. Is "<<" overloaded to dereference
> a char ptr?

Yes

> If so, why not for an int ptr?

How would you expect it to work for int ptr?

> If it is overloaded, why
> does "<< char_ptr" produce a different result from "<< *char_ptr"?

Because in addition to be consistent (char* and char are different types, first points to
possibly more than one character, and the second one is always one character), this is
required by the standard, see 27.6.2.5.4/4

--

Valentin Samko - http://www.valentinsamko.com

### Alberto Ganesh Barbati

Feb 8, 2006, 8:25:17 AM2/8/06
to
dave ha scritto:

> I think I understand that
>
> char * ptr = "string"
>
> declares a pointer initialized to a possibly modifiable constant string.

Your understanding is not entirely correct. 2.13.4/2 says that "The
effect of attempting to modify a string literal is undefined." So, if
you modify the string, you do it at your own risk: the application may
run without errors or ignore the modifications or crash or even format

In fact the type of a string literal is "array of n const char" (notice
the const). The quirk is that a string literal can be used to initialize
a char*. This is an exception whose use is deprecated and that is kept
mainly for backward compatibility with C and older C++ programs.

> Why is the non-deferenced char_ptr not an address in memory?? The
> non-dereferenced int_ptr result is. Is "<<" overloaded to dereference
> a char ptr? If so, why not for an int ptr? If it is overloaded, why
> does "<< char_ptr" produce a different result from "<< *char_ptr"?

Don't confuse "to be an address in memory" with "to be output on cout as
something that resembles an address in memory"! operator<< simply
provides a textual representation of the right operand, but what the
"textual representation" is can differ according to the type of the
argument.

textual representation of integers, floats, etc. and among them there
are overloads for const char* and for const void*. A const char* is
assumed to be pointing to a null-terminated character string, so its
textual representation is the characters in the string itself. Compare
with the typical statement

std::cout << "hello, world\n";

That explains why your char* is output as a string and not as an address.

With const void* you can't assume that it points to anything meaningful,
so the operator<< behaves as the printf "%p" format specifier which
outputs an implementation-defined representation of the pointer
(typically, its address in numeric form).

For pointer types different from const char* (including signed and
unsigned variations) the compiler always choses the overload for const

HTH,

Ganesh

### kanze

Feb 8, 2006, 9:01:40 AM2/8/06
to
dave wrote:
> I think I understand that

> char * ptr = "string"

> declares a pointer initialized to a possibly modifiable
> constant string.

Not quite. The string is not "possibly modifiable"; it's not
modifiable at all. The lack of const in the type is a lie,
supported for reasons of backward compatibility only; you really
should write this:

char const* ptr = "string" ;

> So, I thought I knew what I would see when I ran the following:

> char * char_ptr = "stringthingy";
> int integer = 1234;
> int * int_ptr = &integer;
> ...
> cout << "Size of char_ptr is " << sizeof(char_ptr) << "\n\n";
> cout << "*char_ptr = " << *char_ptr << "\n";
> cout << "char_ptr = " << char_ptr << "\n";
>
> cout << "Size of int_ptr is " << sizeof(int_ptr) << "\n\n";
> cout << "*int_ptr = " << *int_ptr << "\n";
> cout << "int_ptr = " << int_ptr << "\n";

> But, I was surprised to see this result:

> Size of char_ptr is 4
> *char_ptr = s
> char_ptr = stringthingy

> Size of int_ptr is 4
> *int_ptr = 1234
> int_ptr = 0x804e03c

> Why is the non-deferenced char_ptr not an address in memory??
> The non-dereferenced int_ptr result is. Is "<<" overloaded to
> dereference a char ptr?

Exactly. (For char const*, actually, but the conversion to char
const* is better than the convertion to void const*.)

> If so, why not for an int ptr?

Because the overload for char const* was necessary to support
string literals. You cannot define a function to take a char
const[] (the actual type of a string literal) as a parameter;
the closest you can come is a function which accepts char
const*.

> If it is overloaded, why
> does "<< char_ptr" produce a different result from "<< *char_ptr"?

Because the overload of << for char (the result type of
*char_tpr) outputs a single char -- which is all it can do, if
we also allow "<< '\n'" and such things. The overload of char
const*, on the other hand, interprets the address as the start
of a '\0' terminated string.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

### Francis Glassborow

Feb 8, 2006, 11:39:16 AM2/8/06
to
In article <gO9Gf.83683\$eD5.1...@twister2.libero.it>, Alberto Ganesh
Barbati <Alberto...@libero.it> writes

>For pointer types different from const char* (including signed and
>unsigned variations) the compiler always choses the overload for const

I suspect not. What if I provide an overload for operator << that takes
a mytype* as an argument:

ostream & operator << (ostream &, mytype * const &);

--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

### Kurt Stege

Feb 8, 2006, 2:19:13 PM2/8/06
to
Valentin Samko wrote:
> dave wrote:
>
>> char * ptr = "string"
>>declares a pointer initialized to a possibly modifiable constant string.
>
> It's not modifiable. ptr is modifiable, the string it points to - no.

Yes. Here you are more or less right. It is allowed to write the
code *ptr='x'; but when executing that line it results in undefined
behaviour.

I suppose, dave noticed this curious behaviour of C++ and thus
called id "possibly modifiable", as "you can but you can't".

>>So, I thought I knew what I would see when I ran the following:
>> char * char_ptr = "stringthingy";
>> int integer = 1234;
>> int * int_ptr = &integer;
>> cout << "*int_ptr = " << *int_ptr << "\n";
>
> And here you get an undefined behaviour, as you are dereferencing an int ptr which points
> to a storage area which was not initialised as an integer.

You have noticed the line int_ptr = &integer?

Best regards,
Kurt.

### Valentin Samko

Feb 9, 2006, 4:53:00 AM2/9/06
to
Kurt Stege wrote:
>>> char * ptr = "string"
> Yes. Here you are more or less right. It is allowed to write the
> code *ptr='x'; but when executing that line it results in undefined
> behaviour.
I wouldn't say that something is "doable" in a language if this results in an undefined
behaviour. Otherwise one could say that dereferencing a 0 pointer is allowed in C++.

>> And here you get an undefined behaviour, as you are dereferencing an int ptr which points
>> to a storage area which was not initialised as an integer.
> You have noticed the line int_ptr = &integer?

No I haven't :) There is no undefined behaviour there.

--

[ See http://www.gotw.ca/resources/clcm.htm for info about ]

### Alberto Ganesh Barbati

Feb 9, 2006, 5:09:28 AM2/9/06
to
Francis Glassborow ha scritto:

> In article <gO9Gf.83683\$eD5.1...@twister2.libero.it>, Alberto Ganesh
> Barbati <Alberto...@libero.it> writes
>> For pointer types different from const char* (including signed and
>> unsigned variations) the compiler always choses the overload for const
>> void* and that's why your int* is output as an address.
>
> I suspect not. What if I provide an overload for operator << that takes
> a mytype* as an argument:
>
> ostream & operator << (ostream &, mytype * const &);
>

Sure, I should have said "always choses the overload for const void*