Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does printing a string array output hexadecimal?

Tags:

c++

string

c++11

Why does the following program print "0x2ffee4" to the console?

#include <string>
#include <iostream>

using namespace std;

int main() {
    string city1[] = "toronto";
    cout << city1;
    return 0;
}
like image 416
wazeeer Avatar asked May 13 '15 22:05

wazeeer


2 Answers

The first line shouldn't compile, but there's a GCC bug that makes it compile and behave equivalently to something like

std::string city1[] = {"toronto", "toronto", "toronto", "toronto",
                       "toronto", "toronto", "toronto", "toronto"};

(8, because "toronto" is 8 characters including the terminating null. Yes, that means that if you used "Chargoggagoggmanchauggagoggchaubunagungamaugg", it would create an array of 46 strings, each storing "Chargoggagoggmanchauggagoggchaubunagungamaugg".)

Needless to say, you shouldn't rely on a compiler bug.

Under GCC's buggy behavior, city1 would be an array of std::strings; there's no operator << overload that support printing such a thing. Instead, in std::cout << city1, the array decays to a pointer to its first element, and the address stored in the pointer is printed instead.

You probably meant to write std::string city1 = "toronto";. One string, not an array of it.

like image 153
T.C. Avatar answered Oct 26 '22 23:10

T.C.


The answer given by T.C. is correct, I would also like to mention that if you was expecting to print out "toronto" to the console using cout then you would want to do this:

include <string>
include <iostream>

int main() {
    using namespace std;

    // string city1[] = "toronto"; // Compiler Error - Do Next Line Instead
    string city1[] = { "toronto" };
    cout << city1[0];

    return 0;
}

Any time you want to initialize an array of any type during declaration you need to use = { }; To set each array's element separated by commas. Look at this code sample:

#include <string>
#include <iostream>

int main() {
    using namespace std;

    string cities[] = { "New York", "Philadelphia", "Chicago", "Boston" };

    // Same As Above Except Size Of Array Is Defined First Then The Elements
    string cities[4];
    cities[0] = "New York";
    cities[1] = "Philadelphia";
    cities[2] = "Chicago";
    cities[3] = "Boston";

    unsigned index = 0;
    for ( ; index < 4; index++ ) {
        cout << cities[index] << endl;
    }

    return 0;
}

If you are not initializing the array when declaring it then you must specify the array's size.

int main() {
    int iArray[]; // Compiler Error
    int iArray[] = { 4, 3, 2, 1, 6 }; // Okay and is the same as

    int iArray[5];  // Okay
    iArray[0] = 4;
    iArray[1] = 3;
    iArray[2] = 2;
    iArray[3] = 1;
    iArray[4] = 6;

    return 0;

}

If you are not using the bracket operator with an index value to send to the console output stream std::cout then the hex value you are getting is correct as T.C had already stated; it is returning the address of the first index. This is why in c / c++ arrays and pointers are similar (they are not the same, but behave almost like one another). The main difference with arrays is that they are constant in size, the size has to be known at compile time, and can not be dynamically changed in size without having to store the contents into a temp variable while creating a new array with a larger size then copying all the data into the new array and then cleaning up the old array. With pointers they do not behave this way, pointers can be dynamically allocated on the heap using new, but also must be deleted when that variable has no more use to prevent memory leaks, if the pointer is delete before hand and something tries to access it that memory address is no longer valid and doesn't belong to the caller, these are normally seen as unhandled exceptions, heap corruption, etc. and will crash your program. The same goes for arrays when you try to index them past their bounds.

#include <iostream>

int main() {
    // Arrays Are 0 Indexed
    int iArray[3] = { 1, 2, 3 };

    // If you try to do this to access the last element
    std::cout << iArray[3] << std::endl; // Program Will Crash

    // Since Arrays Are 0 Indexed And The Size Of The Array Is 3
    // The 3rd Value Is Indexed At 2, And By Trying To Index Location Of Array
    // At 3, This Memory Doesn't Belong To You, And It Is Undefined Behavior.
    // This Memory Could Contain Nothing, Random Data, Or Even Data That Belongs To 
    // Something Else Which If Changed Can Even Cause System Failure          

    return 0;
} 
like image 28
Francis Cugler Avatar answered Oct 27 '22 00:10

Francis Cugler