Character Array & Pointer - Confused

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
int main()
{
    char arr[] = {'F', 'C'};
    std::cout << arr+0 << std::endl; // FC
    std::cout << arr << std::endl;  //  FC
    std::cout << &arr << std::endl; // 0x7ffcce5b583e
    std::cout << &arr+0 << std::endl; // 0x7ffcce5b583e
    
    // arr+0 -> &F , how I visualise the pointer?
    // arr+1 -> &C , how I visualise the pointer?
      
}


I am trying to understand character arrays. Using the code above as an example:

I have heard people saying arr is a pointer to the first element or first character. If this is the case then how come when printing arr it does not print the memory address if arr is a pointer which should hold a memory address?

Not sure if I understand it properly can someone please help me understand, thanks
Last edited on
Try it with an array of ints rather than an array of chars.

Anything that looks like a char* when being output is assumed to mean, output the string this points to.

To see the pointer value, you have to cast it to some other type.
std::cout << reinterpret_cast<void*>(arr) << std::endl;

> std::cout << arr+0 << std::endl; // FC
Your array lacks an explicit \0, meaning you may find an arbitrary amount of garbage printed after it, or it just crashes.
char arr[] = {'F', 'C', '\0'};

Normally, we do this, which gives us the \0 without additional effort.
char arr[] = "FC";
I have heard people saying arr is a pointer to the first element or first character.

This is not true. arr is an array. However, when you use it it will automatically decay to a pointer to the first element in many situations so you can often use it as if it was a char*.

 
std::cout << arr << std::endl;

It's not actually arr that is being passed to the << operator here. Instead what happens is that arr decays to a pointer to the first element and that's what being passed to the << operator.

When printing a char* using cout<< it will assume it points to a character in a null-terminated array. It will step through each character until it finds a null character '\0'. If the array does not contain a null character it leads to undefined behaviour (UB), i.e. no guarantees what will happen (what usually happens is that it just continues printing whatever garbage that is located after the array in memory until it finds a null character [zero byte] or crashes because it tries to access memory that it's not allowed to).

A string literal like "abc" gives you such a null-terminated char array that you can print without problem.

1
2
3
4
5
6
7
std::cout << "abc"; // OK, prints "abc"

char str[] = "abc";
std::cout << str; // OK, also prints "abc"

char str[] = {'a', 'b', 'c', '\0'}; // this has the same meaning as line 3
std::cout << str; // OK, also prints "abc" 


But your array arr is not null-terminated (it does not contain a null character) so trying to print it is technically UB, meaning it's not guaranteed to output "FC".

This does the same thing.
 
std::cout << arr+0 << std::endl;
arr decays to a pointer when + is used and then you add nothing to that pointer so it's still a pointer to the first element, and of course it's still UB.

Printing any pointer type other than char* will print the address that the pointer holds. &arr gives you a pointer to arr. The type of that pointer is char(*)[2] (pointer to array of 2 chars). So when you print that pointer it'll print the address (i.e. the address where the first byte of the array arr is stored in memory).
Last edited on
salem c wrote:
To see the pointer value, you have to cast it to some other type.
std::cout << reinterpret_cast<void*>(arr) << std::endl;

I think it's a good idea to prefer static_cast over reinterpret_cast whenever possible because it's less "dangerous".

 
std::cout << static_cast<void*>(arr);
Last edited on
Topic archived. No new replies allowed.