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'
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 ) );
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.
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.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why can't I edit a char in a char*?
char *k ;
void ffill()
{
char *d="ddddd";
*k=*d; //expecting to copy "ddddd" to *k
cout<<k<<"\n";
*d[1]=5; // trying to change array element
cout<<k<<"\n";
}
int _tmain(int argc, _TCHAR* argv[])
{
ffill();
cout<<k<<"\n";
}
procedure fill initializes character array k with help of local variable. I'm not sure it copies "ddddd" variable pointer (that is wrong, because after automatic destruction of d memory is not safe) or it copies value and after this *k is initialized correctly.
How to aces *d array element? Compiler is not happy about *d[1]=5;
(Disclaimer: this answer only covers C++. It is not recommended to ask for both C and C++, as both languages are quite different)
Prologue
char *k ;
This declares a pointer to a character.
"ddddd"
This expression has type char const[6], that is, an array of six constant characters. Expressions of this type can be implicitly converted to a pointer to the first element of the array. The type of that pointer is char const*, that is, a pointer to a constant character. A char const* is not convertible to a char*, because char* permits modification of the character it points to, while char const* doesn't.
char *d="ddddd";
Due to the rules outlined above, this statement is not correct. You should turn on the warnings on your compiler and it will warn you against this (ideally it would actually be an error, not just a warning). It should be char const* d = "ddddd"; if you really want a pointer or char d[] = "ddddd"; if you want an array. The second form doesn't need const because it makes a copy, and thus runs no risk of changing the original data, which is const.
*d
This expression involves the implicit conversion to char const* mentioned above, and then the indirection operator (the *) is applied to it, resulting in an expression of type char const&, that is, a reference to a constant character.
*k
Similar to *d, this performs indirection on a pointer. In this case, k is of type char*, so the resulting expression has type char&.
*k=*d; //expecting to copy "ddddd" to *k
The assignment assigns a single character, because it's assignment from a reference to a constant character into a reference to a character. It ends up assigning the first character of the string to the character pointed by k, which is... wait.
Where does k point to? It was never initialized! This is bound to end in tragedy.
Chapter 1
So, how do we get k to point somewhere? And how do we copy the whole string from d into that space?
To copy the six characters of the d array into k, we need space for six characters. The simplest way of doing this is to just make an array of six characters.
char k[6];
Now, how to copy the six elements? We can use the C library function strcpy, which copies null-terminated strings. This function needs a lot of care to use because:
It requires the source to have a null ('\0') character marking the end; if the source does not have such a character, the behaviour is undefined and anything can happen. This is why the string "ddddd" has six characters and not 5: there's an implicit \0 character at the end that the compiler inserts for you.
It requires the destination to have enough space for the whole source string including the null terminator. If the destination doesn't have enough space, the behaviour is also undefined and anything can happen.
This is how this function could be used to make a copy of the string:
std::strcpy(k, d);
Failure to meet either point #1 or #2 can result in anything, from the program seemingly working (if you're unlucky), to acting randomly in strange way, to simply crashing (if you're lucky).
Epilogue
Man, that was a lot of information. Do C++ programmers have to care about these matters all the time? That must be tiresome.
Well, C++ programmers can use std::string instead of character arrays and get a lot less hassle with this: we can make copies with the assignment operator, we don't need to track the correct sizes, we don't need to care for having the null terminators in place, we don't need to limit the size at compile time, and a bunch of other advantages.
std::string k;
void ffill()
{
std::string d="ddddd";
k = d;
cout<<k<<"\n";
d[1]=5;
cout<<k<<"\n";
}
With C programming langage, you should use an array rather than a pointer (because it may point to a read-only string). For example :
char *k;
void
fill(void)
{
char d[] = "ddddd";
k = d;
d[1] = '5'; // Did you mean '5' ?
}
Like Martinho Fernandes already stated: It seems like you're trying to use 'std:string', instead of char arrays.
char k[20] ; //*k doesn't allocate any memory for you to use.
void ffill()
{
char *d="ddddd"; //This works, since it points to the constant character string in your code. But it can not be altered in any way. (It's a 'const char *')
strcpy(k, d); //This standard function copies the content of one pointer to another.
cout<<k<<"\n"; //Not too sure, but it should work,
k[1]=5; //k is the 'changeable memory, not 'd'.
cout<<k<<"\n";
}
There are several things going on here that you need to be aware of. Let me try to explain:
char *k ;
This line declares a variable called k which is a pointer to a character. However, it is not initialized to point to anything. Trying to use an uninitialized pointer will result in undefined behavior.
void ffill()
{
char *d="ddddd";
This line declares a variable named d which is also a pointer to a character. At the same time, you initialize the pointer to point to a constant character array (also called a c-string) that contains 5 'd' characters and a terminating NULL character (so the array has 6 elements).
*k=*d; //expecting to copy "ddddd" to *k
This line uses the dereference operator (*). This operator copys the character pointed to by d and places it at the address pointed to by k. As I noted above, this will result in undefined behavior since the address in the pointer k has not been initialized.
cout<<k<<"\n";
*d[1]=5; // trying to change array element
First of all, you are trying to assign an int to a char. Both C and C++ allow this, but you probably won't get what you expect. In this case, you are trying to replace the second 'd' character with the character code 5. In ASCII, this is a non-printing character.
Also, since d points to a c-string constant, trying to change its elements results in undefined behavior.
cout<<k<<"\n";
}
int _tmain(int argc, _TCHAR* argv[])
{
ffill();
cout<<k<<"\n";
}
There are some other issues with copying one c-string to another, but this is all the detail I will go into here. As other people mention, using std::string is simpler. However, I also believe that learning how to use c-strings is very educational and can improve your coding skills.
Let's see:
*k=*d; //expecting to copy "ddddd" to *k
This won't copy the "string", only tries to set the memory pointed by k to the first character of d. If it is not initialized, then it will fail badly.
*d[1]=5; // trying to change array element
This will also fail. First of all, this is a double indirection. The d[1] = 5; would be betted, but that would also fail, because the string is most probably stored in read-only memory.
Use string instead.
You need to declare d as an array and not a pointer.:
char d[]
d[1] = '5'; // d is a char array, so did you mean the character '5'?
And change
*k=*d; to k = d; //This will copy the value of the pointer
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.