1

I just started learning C++. I have confusion while printing out the int array it is printing the 0th element address of the array. And (array + 1) is the address after 4 registers since int is 4byte. But for char array, the behavior is not the same. Is char array implemented differently in C++?

code:

#include <iostream>

using namespace std;

int main()
    {
    char char_array [5] {'a', 'e', 'i', 'o', 'u'};
    int int_array [5] {1,2,3,4,5};
    cout << sizeof(char) << endl;
    cout << sizeof(int) << endl;
    cout << char_array << endl;
    cout << char_array+1 << endl;
    cout << int_array << endl;
    cout << int_array + 1 << endl;
}

output:

1
4
aeiou≡r
eiou≡r
0x61fe00
0x61fe04

Process returned 0 (0x0)   execution time : 0.428 s
Press any key to continue.
Epsi95
  • 8,832
  • 1
  • 16
  • 34

5 Answers5

4

For starters the program has undefined behavior because the declared character array

char char_array [5] {'a', 'e', 'i', 'o', 'u'};

does not contain a string but using the overloaded operator << in these statements

cout << char_array << endl;
cout << char_array+1 << endl

for a pointer to char requires that the pointer would point to a string.

You could at least declare the array like

char char_array [6] {'a', 'e', 'i', 'o', 'u', '\0' };

Using an integer array as an expression in the operator << results that the overloaded resolution selects the operator for the type void * and the operator outputs the address of the first element of the integer array.

In these statements

cout << char_array+1 << endl;
cout << int_array + 1 << endl;

there is used the pointer arithmetic. The expression char_array+1 or int_array + 1 increases the value or the pointer (the array designator in such an expression is implicitly converted to pointer to its first element) by the value equal to sizeof( char ) or sizeof( int ) correspondingly.

sizeof( char ) is always equal to 1. sizeof( int ) depends on the used system and usually at least for 32-bit systems is equal to 4. And this output

0x61fe00
0x61fe04

demonstrates this.

If you want to output addresses for elements of the character array then you should write for example

cout << static_cast<void *>( char_array ) << endl;
cout << static_cast<void *>( char_array+1 ) << endl;
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Thanks, Vlad, but my intuition was that char_array would print memory address of 'a' and char_array + 1 would print memory address of 'e' – Epsi95 Apr 22 '20 at 19:26
  • @Epsi95 In this case you need to write for example cout << static_cast( char_array ) << endl; – Vlad from Moscow Apr 22 '20 at 19:28
  • 1
    @Epsi95 In C strings were simply null-terminated char arrays, so there is a special overload of the `<<` operator for char pointers which will print the null-terminated string at the address instead of the address itself. – eesiraed Apr 22 '20 at 19:32
  • @Vlad great now I am getting 0x61fe1a, 0x61fe1b exactly 1 byte. Need to go long way seems :p. Although I am unable to fully understand the reasoning, all I could gather is the overloading operator << is doing something with the char pointer that is why its behavior is different from int pointer. – Epsi95 Apr 22 '20 at 19:33
  • @BessieTheCow great, thanks for the clarification! – Epsi95 Apr 22 '20 at 19:37
  • 1
    @Epsi95 For a character pointer the overloaded operator << assumes that the pointer points to a string and outputs the pointed string. – Vlad from Moscow Apr 22 '20 at 19:40
1

char[5] gets decayed to char const *, and then there is an overload for operator<< that writes out the string represented by the char const *.

int[5] decays to int const *, but there is not a similar overload for int const *, and so it simply prints the address.

cigien
  • 57,834
  • 11
  • 73
  • 112
1

std::cout is a variable of type std::basic_ostream which has an overload especially for formatting char*. Which is important because raw arrays will decay to pointers when passed by value.

The unique overload of operator<< for char* expects that the incoming data is a C String. Which is a string of characters that is nul terminated.

char char_array [5] {'a', 'e', 'i', 'o', 'u'};

Creates an array which is not nul terminated which is why you get seemingly random characters (via a buffer over read, leading to undefined behaviour). To rectify that you would just need to include a nul terminator. When char_array is declared as :

char char_array [6] {'a', 'e', 'i', 'o', 'u','\0'};

then

std::cout << char_array << std::endl;

will output aeiou and

std::cout << char_array + 1 << std::endl;

will output eiou

George
  • 2,101
  • 1
  • 13
  • 27
  • Thanks, George, but my problem was not that it is printing some random char after "aeiou" as there is no null termination but why I was not getting the memory address. – Epsi95 Apr 22 '20 at 19:24
  • @Epsi95 Reading past the end of an array is undefined behavior. You're not guaranteed to get random characters. – eesiraed Apr 22 '20 at 19:33
  • @BessieTheCow yes true, random char is not a proper word, it's undefined value. – Epsi95 Apr 22 '20 at 19:44
-1

Here int_array is a pointer to an array of int. When you print int_array, you are printing the address of the start of the array (0x61fe00 in you case). When you print int_array + 1 your are doing what is called pointer arithmetic: int_array + 1 could be roughly translated as give me the next address holding and int and as int is 4 bytes, you can see that the next address is effectively the address plus four.

char_array is also a pointer to an array of char. Passing a pointer to an array of char while effectively print the underlying string. Here your string misses the end character `\0' which is UB.

You should definitively read on what is a pointer and a value because it is clear here that you are missing that knowledge.

Thomas Caissard
  • 846
  • 4
  • 10
-2

A char array is a string and is being output as one.

jkb
  • 2,376
  • 1
  • 9
  • 12