Char array questions

Questions from a noob here about char arrays.

So I understand that operator<< is overloaded for char* to print all characters until the null terminator, so using cout directly on a char array's name will print it out, rather than the address of its first character.

But what I dont understand is why casting it with (void*) changes that, and it actually prints out the address of the char array. What exactly is happening behind the scenes here?

And how would one print the address of every character in a char array? Which brings me to the code below.

Why does this happen?

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
using namespace std;

int main()
{
    char *test = "Testing 123 ";
    
    cout << &test[0] << endl; // both of these cout statements
    cout << test << endl; // print  "Testing 123" ??
    
    return 0;
}


I was expecting line 3 to print out the address of the 0th character, but it instead prints out the entire array.

What is going on here?

When you pass a char-pointer to cout, it prints out the char being pointed to and every value in every subsequent memory location until it finds the value zero.

&test[0] This is a char-pointer, pointing to the first char in the array, so cout outputs that char and every char following it, until it finds a zero (which in this case, is right after the final space you've got there).

test This is a char-pointer, pointing to the first char in the array, so cout outputs that char and every char following it, until it finds a zero (which in this case, is right after the final space you've got there).


You're passing two identical char-pointers, so you get identical results.


If you want it to print out the address of the zeroth character, you need to pass it something that ISN'T a char-pointer. If you pass cout a void-pointer, cout has been programmed to output the value of that pointer - NOT what it's pointing at. When you pass cout a char-potiner, cout HAS been programmed to output what that pointer is pointing at.

What exactly is happening behind the scenes here?

Behind the scenes, the function that gets called when you pass cout a char-pointer is different to the function that gets called when you pass cout a void-pointer. Different code is executed.
Last edited on
Don't do this: char *test = "Testing 123 "; // *** error: ISO C++11 does not allow conversion from string literal to 'char *'
http://coliru.stacked-crooked.com/a/2d97fae0360a34fe

Either: char test[] = "Testing 123 " ; or const char* test = "Testing 123 " ;
I see, this is becoming clearer now. Just a couple questions.

&test[0] This is a char-pointer, pointing to the first char in the array, so cout outputs that char and every char following it, until it finds a zero (which in this case, is right after the final space you've got there).


Why isn't cout << &test[0] << endl; interpreted as "print address of 0th element of test" ? Im explicitly using the address operator here...

Don't do this: char *test = "Testing 123 "; // *** error: ISO C++11 does not allow conversion from string literal to 'char *'
http://coliru.stacked-crooked.com/a/2d97fae0360a34fe

Either: char test[] = "Testing 123 " ; or const char* test = "Testing 123 " ;


This must be a c++11 thing, because it compiles fine in c++98.

So in c++11, char* is different from char[]?
char* is the same as char[]. Only difference is that when you say char* pToChar = "Hello World"; you are declaring a pointer that points to the text "Hello World" which is located somewhere on your computer's memory. Generally speaking, most of the times you wouldn't want to do that. Use strings instead as often as you can when you're working in C++.

An array is really just a constant pointer to its very first element. When you pass an array to a function, you're literally just passing a pointer. If you want proof of this, try it out yourself. Create an array, pass it to a function that increments the array elements by some value, display the elements in main, and you will notice that the values would have changed.
Arslan7041 wrote:
Why isn't cout << &test[0] << endl; interpreted as "print address of 0th element of test" ? Im explicitly using the address operator here...

The compiler use the type to decide which version of operator<< to call. The type of &test[0] is char*, the type of test is also char*, so the same operator<< overload will be used for both of them.
Thanks to everyone who replied. This was very helpful.

> So in c++11, char* is different from char[]?

In every version of C++, char* is different from char[].
The type char* is pointer to char
The type char[n] is array of n char

The type of a narrow string literal was array of n char in C++98, it is array of n const char in C++11.
In both, a string literal is an object with static storage duration.

char test[] = "abcd" ; "abcd" is a string literal; an array of 5 const char with static storage duration. The type of test is array of 5 char; it is initialised with the characters in the string literal.

const char* ptr = "abcd" ; The type of ptr is pointer to const char, it is initialised with a pointer to the first character of the array (string literal).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>

int main()
{
    char array[] = "abcdefghijklmnop" ;
    const char* pointer = "abcdefghijklmnop" ; // array to pointer conversion
    const char* pointer2 = "abcdefghijklmnop" ;

    using pcv = const void* ;
    std::cout << "sizeof( \"abcdefghijklmnop\" ) == " << sizeof( "abcdefghijklmnop" ) << '\n' // 17
              << "sizeof(pointer) == " << sizeof(pointer) << "\n\n"
              << "&array[0] == " << pcv(&array[0]) << '\n'
              << "&\"abcdefghijklmnop\"[0] == " << pcv(&"abcdefghijklmnop"[0]) << '\n'
              << "pointer == " << pcv(pointer) << '\n'
              << "pointer2 == " << pcv(pointer2) << '\n' ;
}

sizeof( "abcdefghijklmnop" ) == 17
sizeof(pointer) == 8

&array[0] == 0x7fff8d92bc70
&"abcdefghijklmnop"[0] == 0x401770
pointer == 0x401770
pointer2 == 0x401770

http://coliru.stacked-crooked.com/a/21011c6b594b2c2c

Evaluating a string-literal results in a string literal object with static storage duration, initialized from the given characters ... Whether all string literals are distinct ... and whether successive evaluations of a string-literal yield the same or a different object is unspecified. - IS

In most implementations, successive evaluations of a particular string-literal within the same unit of translation yield the same object. Here, successive evaluations of "abcdefghijklmnop" yield the same array of 17 const char
Last edited on
Topic archived. No new replies allowed.