This question already has answers here:
cout << with char* argument prints string, not pointer value
(6 answers)
Closed 8 years ago.
Today i have learned about pointers and i have this:
char message[]="hello everyone";
char *pm;
pm=message;
cout<<&pm[0];
This would output hello everyone, I want to know why? because & should output the address of pm[0] not the hole value. Can someone explain?
&pm[0] is of type char*. << is overloaded for char const* to print all characters until '\0'. If you want to print the address you have to convert it to void* first.
message is an array of chars containing hello everyone\0.
When you do pm = message;, the array message undergoes array-to-pointer conversion, which gives you a pointer pointing at the first element in the array. So pm now points at the very first char in the array (the h character).
pm[0] is equivalent to *(pm + 0), which basically just gives you the first character in the array. Then &pm[0] is taking the address of that character, giving you a pointer to the first character. So pm and &pm[0] are exactly the same.
cout has a special overload for handling char*s. When you pass a char* to cout, it assumes that you want it to print it out like a C-style string, where the char* is pointing at the first character in an array of characters that end with \0.
&pm[0] is the same as &(*(pm+0)) which is the same as &(*pm) which is the same as pm. And pm points to the first element of the zero-terminated character array message.
Now, the << operator for the output stream, when passed a char* or const char* treats that as a pointer to a null-terminated array of characters. That is, a C string.
So, the entire contents of the string are output to the output stream.
& should output the address of pm[0]
No, the & operator is not related to the output. The & operator is part of the expression &pm[0]. This expression is evaluated, as described above. And the result of that evaluation is passed to the best matching overload of the output stream's << operator. It is the << operator that determines how the value of your expression is output, and that determination is based on the type of your expression.
In order to output an address, you would need to supply an argument of a different type, for instance void*. You can cast the char* pointer like this:
static_cast<const void*>(&pm[0])
Usually, giving a pointer to std::cout will result in the pointer's value (the memory address it contains) being printed.
However, there is a special case for [const] char*, which is automatically assumed to be a C-style string and therefore dereferenced to be treated like one. This (in concert with array name decay) is to allow you to do things like std::cout << "Hello world\n"; without just getting a memory address instead.
Related
If I execute this code:
#include<iostream>
using namespace std;
int main(){
char str[20] = {'a','b','c','d','e'};
cout<<str<<endl;
return 0;
}
It outputs abcde but If I execute this code:
#include<iostream>
using namespace std;
int main(){
int arr[20] = {1,2,3,4,5};
cout<<arr<<endl;
return 0;
}
It outputs 0x7fff22eecc30 I have tried executing this code in two different online compilers and they are giving same outputs.
In char array it is returning the array contents but in int array it's returning memory address. Why is that? Also, how can two different online compilers return the same memory address?
I have tried looking out online for this but I'm not sure what to look for?
With char str[20] = {'a','b','c','d','e'};, the remaining 15 elements of the array are all set to 0. The special ostream overload for << that's used as a result of the array str decaying to a char* pointer to the first element of that array will output the array as if it's a C-style string, since the first 0 will act as a NUL terminator.
An equivalent way of writing the above is char str[20] = "abcde".
In your second case, the overloaded << for ostream for a const void* pointer is used (due again to pointer decay), which prints the address of the first element of the array.
What std::cout knows how to print
Under the hood cout is an object derived from the basic_ostream class template. The standard library provides some functions that tell basic_ostream how to print different types of data. (Some are member functions, some aren't - but that's not important here.)
Here are some examples:
basic_ostream<charT,traits>& operator<<(bool n);
basic_ostream<charT,traits>& operator<<(short n);
basic_ostream<charT,traits>& operator<<(int n);
basic_ostream<charT,traits>& operator<<(double f);
... and more ...
These functions tell cout (and other basic output streams) how to print bools, shorts, ints, etc.
There's also these two
basic_ostream<charT,traits>& operator<<(const void* p);
template<class traits>
basic_ostream<char,traits>&
operator<<(basic_ostream<char,traits>&, const char*);
The first one tells cout how to print the address of an untyped pointer (a void*).
The second one is intended to print C-style strings --- especially literal strings in your source code. For example, cout << "Hello";
What about arrays?
The standard library doesn't provide any direct support for printing arrays (or any other collection). If you want to print a collection, you have to decide what format you want for that collection, and code it up yourself.
This is the same for structs and classes. If you define your own class, cout doesn't know how to print it --- you must code that up yourself.
Why does your first example output "abcde"?
You're trying to print a char[20] (an array of char). basic_ostream doesn't have an overloaded << function for arrays, so it doesn't know how to print them.
BUT - C++ is allowed to implicitly cast an "array of T" to a "pointer to T", so your str variable is implicitly cast from char[20] to char*. That matches the last overload I listed above - the one that is supposed to be used for C-style strings. (Other answers have already discussed issues regarding the terminating zero that C-strings are supposed to have.)
What about the second example?
The type of arr is int[20]. Once again, cout doesn't know how to print arrays.
SO - C++ tries implicitly casting your int[20] to an int*. But there is no overload for int*, so C++ tries again. It implicitly casts the int* to a void* (which it is allowed to do) - and now it finds a match.
The void* overload prints the memory address of the pointer.
This happens with all arrays except arrays of char, signed char and unsigned char. The array of T is cast down to a pointer to T, which is cast down to a void pointer.
Why is char* treated differently than any other pointer type
Because we print C-style strings (especially string literals) a lot. Like, a lot a lot.
The most often usage of character arrays is the usage them as containers of strings. It is very easy to determine the size of a string due to its sentinel value that is the terminating zero character.
So if in a C program you will write for example
char str[20] = {'a','b','c','d','e'};
printf( "%s", str );
then the call of printf easy outputs the string "abcde" because it is well-knowb where to stop outputting characters of the character array.
If in a similar call of printf you will specify an integer array then it is unknown what is the size of the integer array. How many integers stored in the array to output?
So a call of printf for character arrays containing strings is well-defined. However if you are using a pointer of the type int * when it is unclear whether the pointer points to a single integer or a sequence of integers. And if the pointer points to a sequence of integers then what is the length of the sequence?
This approach was carried over to the implementation of the overloaded operator << for character arrays in C++.
Pay attention to that if a character array does not contain a string this such a statement
std::cout << str;
results in undefined behavior. In this case you should use for example the following call
std::cout.write( str, sizeof( str ) );
Consider the output of this code:
char A = 'a';
char B[] = "b";
cout<<&A;
It outputs "ab" (the concatenation of A and B) and I wonder why. Please, explain me this.
Because &A is a char *. A string, represented by a char *, is required to have a '\0' terminating byte.
&A points to a single char, without a following '\0'. As such, attempting to print this text string results in undefined behavior.
You got an unexpected result because the operator << for objects of type char * is overloaded such a way that it outputs strings pointed to by pointers of the type char *.
It seems that your compiler placed the array B after the character A and in the memory they look like one string.
'a' 'b' '\0'
| |
A B
(It is unspecified in the C++ Standard whether A will precede B or B will precede A in the memory and whether there will be a gap due to padding bytes between the objects.)
If you want to output the address of the object A you should write for example
cout<< ( void * )&A;
or
cout<< ( const void * )&A;
or either ,like
cout<< static_cast<void *>( &A );
or like
cout<< static_cast<const void *>( &A );
It is unimportant whether the const qualifier will be specified for the pointer to a non-constant object because. It will be implicitly converted to the type const void * in the operator
basic_ostream<charT,traits>& operator<<(const void* p);
cout expects the char* parameter to point to a zero terminated string. But &A isn't zero terminated, so the precondition fails and this leads to undefined behavior.
Undefined behavior cannot really be explained, because the standard allows anything to happen. Displaying some more characters is one possible result. As is crashing. Or something else.
I wonder why
Because the stream insertion operator requires that any character pointer passed to it must point to a null terminated character string. The pointer passed to cout points to A which is not a null terminated character string. Since the pre-conditions (requirements) of the operation were not satisfied, the behaviour is undefined.
There are two relevant overloads for insertion operator (I've simplified away the template details, and the fact the one of these is a member overload, and the other is not):
ostream& operator<< (const void*);
ostream& operator<< (const char*);
All other pointers implicitly convert to void* and use the former overload and the pointer is outputed as a memory address. But the latter is favoured overload for character pointers, and the argument is required to be a null terminated string.
So, because a character pointer is interpreted as null terminated string, the naïve attempt to print the address of a character does not work. The solution: Cast the pointer to void* explicitly before passing to the stream.
The streams have been designed this way, in order to conveniently support null terminated strings, such as string literals which were considered to be (and are) streamed more typically than addresses. For example, it is convenient that std::cout << "Hello World!";. Prints "Hello World" instead of a memory address where the string literal is located.
This is a compiler-dependent behavior. Often, A nad B will be allocated one after the other on the stack. Taking the address of A will look like the zero-terminated string "ab". Don't do this! You rely on the stack frame layout the compiler is constructing.
because your char is not null terminated.
The behavior for this will UNDEFINED.
Your compiler has placed string comprising 'b' and '\0' immediately after character 'a' so once you've printed your A character as a string it found 'a', followed by 'b' followed by '\0' hence you have printed 'ab'
If you have a look at the code
#include <iostream>
enum Type
{
INT,
FLOAT,
STRING,
};
void Print(void *pValue, Type eType)
{
using namespace std;
switch (eType)
{
case INT:
cout << *static_cast<int*>(pValue) << endl;
break;
case FLOAT:
cout << *static_cast<float*>(pValue) << endl;
break;
case STRING:
cout << static_cast<char*>(pValue) << endl;
break;
}
}
int main()
{
int nValue = 5;
float fValue = 7.5;
char *szValue = "Mollie";
Print(&nValue, INT);
Print(&fValue, FLOAT);
Print(szValue, STRING);
return 0;
}
The line char *szValue = "Mollie";is what confuses me. From what I have been learning is that a pointer is a variable that holds the address of another variable. My issues with that line obviously is that
How come this code accepts a string into a char? We have not specified that this char is an array. Then how come?
How come we are assigning a STRING to a pointer? I thought we could only assign other addresses to them. Where is that pointer getting its address from? Where is it storing the value?
I am still new to C++ but any help would be appreciated.
Update: from what I have understood from the answers below is that when we say "it assigns each letter to the memory addresses in the vicinity of szValue". The rest of the Chars in the string are stored in +1 addresses. How does C++ know how many char / addresses are in the original string? Since szvalue only contains the address of the first char. Not the others right?
Source: LearnCPP - Void Pointers
In a nutshell, in C++ pointers and arrays are almost the same thing. For compiler there is no difference when you define *szValue or szValue[].
A string literal is stored by compiler in memory and first symbol address is actually the value of the string. When you assign a string to char * you might get different use of the that block of memory (i.e. just pass this address into some function or iterate over symbols)
Mind examining more pages of the online tutorial you found pointers-arrays-and-pointer-arithmetic. However I consider the best for learning C++ is reading Bjarne Stroustrup
EDIT: (credits to seand)
Pointers and arrays are almost, but not exactly the same. Take, char *x, and char y[5]. 'y' is like a pointer that points to something fixed, but 'x' may be reassigned. sizeof y yields 5. When passing x or y into functions the arrayness of 'y' disappears
How come we are assigning a STRING to a pointer? I thought we could only assign other addresses to them. Where is that pointer getting its address from? Where is it storing the value?
So, two things.
Except when it is the operand of the sizeof or the unary & operators (along with a couple of others), or is a string literal being used to initialize another array in a declaration, an expression of type "N-element array of T" will be converted ("decay") to an expression of type "pointer toT", and the value of the expression will be the address of the first element of the array.
A string literal is an expression of type "N+1 element array of const char" (plain char in C) where N is the number of characters in the string.
Putting that together,
char *szValue = "Mollie";
the string literal "Mollie" is an expression of type "7-element array of const char". Since it isn't the operand of the sizeof or unary & operators, and since it isn't being used to initialize an array, it is converted to an expression of type "pointer of const char", and its value is the address of the first element.
This is an important point - arrays are not pointers. Arrays do not store a pointer value anywhere. Under certain circumstances the compiler will substitute a pointer expression for an array, but otherwise they're two completely different animals.
The previous two answers have covered the gist of the matter. There are strong similarities between pointers and arrays (arrays can be considered pointers to a memory location themselves). For example, when an array name is used as an argument for a function the memory address of the first element is passed to the function as opposed to the value at that location (which would be the case for an ordinary variable).
The code above assigns a string literal "Mollie" to the char pointer szValue. Therefore starting from the "M" (which is treated as a char not a string) in "Mollie" it assigns each letter to the memory addresses in the vicinity of szValue. Therefore the pointer variable szValue would point to the first element of the string, equivalent to saying szValue[0] (if szValue were declared as a char array).
Hope this helps.
Edit:
Just to be more specific szValue points to the memory address of the first element in the string "Mollie" which is equivalent to using &szValue[0].
The line char* s = "Mollie", in C and C++, means this:
s is a pointer to a character.
It is initialized pointing to the first character in a static character array containing the characters M, o, ... e, and a null character \0.
A pointer is a pointer to a piece of memory containing a type.
That piece of memory is not necessarily a variable.
How come this code accepts a string into a char?
Your code isn't actually doing that, instead it's assigning the address of the first character element to the value of the pointer. Viz, the pointer points to the beginning of the string, incrementing the pointer by 1 will now refer to the next character in the array, and so on.
We have not specified that this char is an array. Then how come?
You have char*, not char, that's the difference. Also, semantically char[] and char* are the same.
Where is that pointer getting its address from?
The compiler sticks the literal string "Mollie" in a read-only portion of the program's memory that is loaded when the program is executed by the operating system. The value of szValue is equal to the address of that string literal. You'll find it's read-only and if you attempt to modify it you'll get a segfault (on *nix) or an Access Violation on Windows.
char *foo declares a char pointer, which in C is how arrays are represented.
So:
char *foo = "ABCD";
foo[1] == 'B'
which also means:
*(foo + 1) == 'B'
The actual type of "Mollie" is const char*. You can think about it as about an array of chars. Thats why you can write something like this:
const char c = szValue[4];
Here, szValue is just a pointer to the first character of the string. Hence, szValue + 1 will be a pointer to the second character and so on.
You should know that when you use char *szValue = "Mollie";, it means you assign the address of constant string "Mollie" to szValue and you can't change value through szValue, because "MOllie" is a constant value stored in constant area.
Pointers have always made me blank about the logic I intend to use in code, If someone can help me understand a few concepts that would be really helpful. Here's a code snippet from my program,
vector <char> st;
char *formatForHtml(string str, string htmlTag)
{
string strBegin;
strBegin = "<";
strBegin.append(htmlTag);
strBegin.append(">");
strBegin.append(str);
string strEnd = "</";
strEnd.append(htmlTag);
strEnd.append(">");
strBegin.append(strEnd);
st.resize(strBegin.size());
for (int i =0;i <strBegin.size();i++) {
st[i] = strBegin.at(i);
}
return &st[0];
}
In the code above if I have to return address of st[0], I have to write the function of type char *. I need to know the reason to do so, also if address is the integer value why can I not define function as an int type?
P.S. It's a beginner level doubt.
You don't tell us what st is, so we can't tell whether the code is
totally incorrect, or just bad design. If st is a typo for str
(just guessing, since str isn't used anywhere), then you have
undefined behavior, and the program is incorrect, since you're returning
a pointer into an object which has been destructed. At any rate, a
function like formatForHtml should return an std::string, as a
value, and not a pointer (and certainly not a pointer to a non-const).
I might add that you don't use a loop to copy string values character by
character. std::string acts as a normal value type, so you can just
assign: st = strBegin;.
EDIT:
Just for the record, I've since reexamined your code. The natural way
of writing it would be:
std::string
formatForHtml( std::string const& cdata, std::string const& tag )
{
return '<' + tag + '>' + cdata + "</" + tag + '>';
}
No pointers (at least not visible---in fact, "+ operator), and full use of
std::strings facilities.
I have to write the function of type 'char *' I need to know the reason to do so
There's no reason to do so. Just return a std::string.
From the looks of your code, st is a std::vector<char>. Since std::vector has continuous memory, &st[0] is the address of the first char in the vector, and thus points to the not null-terminated string that the vector represents, which isn't very helpful outside the function because you can't find the length.
That's awkward code, you're expecting 'str' as an argument, but then you return its memory location? Why not return the string itself?
Your code there has a few typos. (Did you mean 'str' when you typed 'st'? If not, then where is 'st' defined?)
As for why you can't define the function as "int" type, that is because an "int" is a different type to "pointer to char".
Personally, I would return 'string', and just have a 'return str' at the end there.
Pointer is pointer, not integer value. Code is right if and only if st is global variable or declared as static in this function. But return string is preferably, than return pointer.
Why don't you use string as return type for your function?
First: a pointer is an adress of something lying in memory, so you can't replace it with an integer (only with some dirty tricks).
Second: &st[0] is the adress of the internal buffer the string uses to store its content. When st goes out of scope (or is reused for the next call), it will be overwritten or given back to the heap manager, so the one calling this function will end with some garbage.
Btw, most of your function does unnessesary work which the string class can do by itself (for example copiing strBegin to st).
Simple.
string str
is something that contains a bunch characters.
str[0]
return the first character.
Therefore,
&str[0]
gives you the address of the first character, therefore it's a "char *" --- "char" being whatever the pointer points to, "*" being the "address of" part of the pointer. The type of the pointer is about the object being pointed to.
Also, addresses may be just "integers" on the hardware level (everything is an integer... except for integers themselves, they are a bunch of bools), but that doesn't mean anything for a higher level language. For a higher level language, a pointer is a pointer, not an integer.
Treating one as another is almost always an error, and C++11 even added the nullptr keyword so we don't have to rely on the one valid "pointer is an integer" case.
And btw, your code won't work. "str" only exists for the duration of the function, so when the function returns "str" ceases to exist, which means the pointer you have returned points into a big black nowhere.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why does cout print char arrays differently from other arrays?
If I have this code:
char myArray[] = { 'a', 'b', 'c' };
cout << myArray;
It gives me this output:
abc
However, if I have this code:
int myArray[] = { 1, 2, 3 };
cout << myArray;
It gives me this output:
0x28ff30
Why does it not print out 123?
The reason that the first piece of code works is that the compiler is implicitly converting the array into a const char * character pointer, which it's then interpreting as a C-style string. Interestingly, this code is not safe because your array of characters is not explicitly null-terminated. Printing it will thus start reading and printing characters until you coincidentally find a null byte, which results in undefined behavior.
In the second case, the compiler is taking the int array and implicitly converting it into an int * pointer to the first element, then from there to a const void * pointer to the first element. Printing a const void * pointer with cout just prints its address, hence the output you're getting.
Hope this helps!
There is an operator << that knows about basic_ostream instances (such as cout) on the left-hand-side and const char*s on the right.
There is no such operator defined for const int* (or const int[]). Although you are perfectly at liberty to create one.
Just be sure to specify a sentinel at the end of your arrays to prevent running off the end of your buffer.
The reason you see the pointer value is because there is an basic_ostream::operator<<(const void*) which will print this.
std::cout is an instance of std::ostream, and there are several overloaded operators provided.
For example:
std::ostream& operator << (std::ostream&, char*);
When you type std::cout << somevar; compiler looks up best matching overload. First for exact type of the variable, then for anything it can be implicitly converted to (not to mention member functions/free functions/template functions, etc).
Here is a random article on C++ Overload Resolution
When you use myArray in the context cout << myArray;, it decays to a pointer. The operator<< which takes a char* as its second argument outputs a string; the one which takes other types of pointer just outputs an address. Hence the observed behaviour.
Your char array is actually not null-terminated, so I guess what you're seeing in the first case is really just undefined behaviour which happens to do 'the right thing' in this instance.
You haven't passed it an array of ints; you've passed it a pointer to an int. When faced with a pointer, it prints out the address that it points to. It has no way of printing out an array because it doesn't know how many elements it has (if any).
The reason it worked when you used a pointer to a character is that it knows that all arrays of characters are terminated by a NUL (\0) character, so it doesn't matter that you haven't told it the number of characters in your array. Keep in mind that your array is not terminated by a NUL, so it's only by luck that you got abc and no extra garbage characters on the end.
Because it has no way of knowing that your array is an array, or what kind of data is in it. When you do cout << myArray, 'myArray' is treated as a pointer type, which may point to anything. So instead of trying to dereference the pointer (and potentially crashing the app if the pointer has not been initialized), the address that the pointer is pointing to gets printed.