Going by the books, the first cout line should print me the address of the location where the char variable b is stored, which seems to be the case for the int variable a too. But the first cout statement prints out an odd 'dh^#' while the second statement correctly prints a hex value '
ox23fd68'. Why is this happening?
#include<iostream>
using namespace std;
int main()
{
char b='d';
int a=10;
char *c=new char[10];
c=&b;
int *e=&a;
cout<<"c: "<<c<<endl;
cout<<"e: "<<e;
}
There is a non-member overload operator<<(std::basic_ostream) for the const char* type, that doesn't write the address, but rather the (presumed) C-style string1). In your case, since you have assigned the address of a single character, there is no NUL terminator, and thus no valid C-style string. The code exhibits undefined behavior.
The behavior for int* is different, as there is no special handling for pointers to int, and the statement writes the address to the stream, as expected.
If you want to get the address of the character instead, use a static_cast:
std::cout << static_cast<void*>( c ) << std::endl;
1) A C-style string is a sequence of characters, terminated by a NUL character ('\0').
Actually this program has problem. There is a memory leak.
char *c=new char[10];
c=&b;
This allocates 10 characters on heap, but then the pointer to heap is overwritten with the address of the variable b.
When a char* is written to cout with operator<< then it is considered as a null terminated C-string. As the address of b was initialized to a single character containing d op<< continues to search on the stack finding the first null character. It seems the it was found after a few characters, so dh^# is written (the d is the value of variable b the rest is just some random characters found on the stack before the 1st \0 char).
If you want to get the address try to use static_cast<void*>(c).
My example:
int main() {
char *c;
char b = 'd';
c = &b;
cout << c << ", " << static_cast<void*>(c) << endl;
}
An the output:
dÌÿÿ, 0xffffcc07
See the strange characters after 'd'.
I hope this could help a bit!
Related
On printing the &a (cout<<&a), compiler is giving output 'Z' but when we print character before printing character address it gives output(cout<<a<<" "<<&a) as 'Z ZZ'. I know that cout treats character address differently i.e on getting an address of character it doesn't print that address instead it prints the contents which are there at that address. Please help me with the concept i am missing here. Here is the code snippet:
#include <iostream>
using namespace std;
int main() {
char a = 'Z';
cout<<a<<&a;
return 0;
}
char a = 'Z';
cout << &a;
This treats the address of a as an address to a null terminated string and prints this string. Since that is not a pointer to a null terminated string (it's a pointer to a single char) you have Undefined Behavior in your program.
Undefined Behavior means that the program doesn't have a defined behavior, i.e. it can have any behavior: it can print garbage, it can print other garbage, it can print nothing, it can crash or pretty much any behavior.
If you want to output the address of the variable a then write
char a = 'Z';
cout << a << static_cast<void *>( &a );
Otherwise the compiler tries to output a string pointed to by the expression &a that has the type char * until the zero-terminating character is encountered.
Thus this output
cout << &a;
has undefined behavior.
If you want to output the variable a as an array having a string then you have to declare an array instead of the scalar variable and initialize it with a string literal instead of the character literal. For example
char a[] = "Z";
cout << *a << &a;
Please explain the difference in the output of two programs.
cout << branch[i] in first program gives output as:
Architecture
Electrical
Computer
Civil
cout << *branch[i] in second program gives output as:
A
E
C
C
Why?
What is the logic behind *branch[i] giving only first character of each word as output and branch[i] giving full string as an output?
Program 1
#include <iostream>
using namespace std;
int main()
{
const char *branch[4] = { "Architecture", "Electrical", "Computer", "Civil" };
for (int i=0; i < 4; i++)
cout << branch[i] << endl;
system("pause");
return 0;
}
Program 2
#include <iostream>
using namespace std;
int main()
{
const char *branch[4] = { "Architecture", "Electrical", "Computer", "Civil" };
for (int i=0; i < 4; i++)
cout << *branch[i] << endl;
system("pause");
return 0;
}
When you declare a const char* with assignment operator, for example:
const char* some_string = "some text inside";
What actually happens is the text being stored in the special, read-only memory with added the null terminating char after it ('\0'). It happens the same when declaring an array of const char*s. Every single const char* in your array points to the first character of the text in the memory.
To understand what happens next, you need to understand how does std::cout << work with const char*s. While const char* is a pointer, it can point to only on thing at a time - to the beginning of your text. What std::cout << does with it, is it prints every single character, including the one that is being pointed by mentioned pointer until the null terminating character is encountered. Thus, if you declare:
const char* s = "text";
std::cout << s;
Your computer will allocate read-only memory and assign bytes to hold "text\0" and make your s point to the very first character (being 't').
So far so good, but why does calling std::cout << *s output only a single character? That is because you dereference the pointer, getting what it points to - a single character.
I encourage you to read about pointer semantics and dereferencing a pointer. You'll then understand this very easily.
If, by any chance, you cannot connect what you have just read here to your example:
Declaring const char* branch[4]; you declare an array of const char*s. Calling branch[0] is replaced by *(branch + 0), which is derefecencing your array, which results in receiving a single const char*. Then, if you do *branch[0] it is being understood as *(*(branch + 0)), which is dereferencing a const char* resulting in receiving a single character.
branch[i] contains a char* pointer, which is pointing to the first char of a null-terminated string.
*branch[i] is using operator* to dereference that pointer to access that first char.
operator<< is overloaded to accept both char and char* inputs. In the first overload, it prints a single character. In the second overload, it outputs characters in consecutive memory until it reaches a null character.
This is because of operators precedences.
Subscript operator [] has a higher precedence than an indirection operator *.
So branch[i] returns const char * and *branch[i] returns const char.
*branch[i] prints a single char located at the address pointed to by branch[i].
branch[i] prints the whole char* array starting with the address pointed to by branch[i].
While I was using c_str() to transform std::string into C-style string, I didn't see the last character overridden by the null-termination which c_str() is supposed to add in this program:
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
int main()
{
string s = "helloworld";
char c[10];
strcpy(c, s.c_str());
cout << c << endl;
return 0;
}
What I am asking is why d is being printed (added to c) as I was expecting null-termination to be there. What am I missing here?
Your code has undefined behavior, because c, the array into which you copy the string, does not allocate enough space for null terminator.
The number of characters that you copy is 10, so you need an array of 11 to accommodate the null terminator.
To avoid overrun troubles like that with statically allocated arrays, use dynamic allocation instead:
char *c = new char[s.size()+1];
strcpy(c, s.c_str());
cout << c <<endl;
delete[] c;
You have undefined behaviour, "helloworld" is actually "helloworld\0", that is 11 characters. strcpy tries to copy over the whole string including NUL but c is only able to hold 10 characters.
strcpy does not know how long the target array is. It copies until (and including) the terminating 0 byte. So, the whole string helloworld\0 is copied. Note that this is 11 chars and you might as well get a crash.
Why does the following happen?
char str[10]="Pointers";
char *ptr=str;
cout << str << "\n"; // Output : Pointers
int abc[2] = {0,1 };
int *ptr1 = abc;
cout <<ptr1 << "\n"; // But here the output is an address.
// Why are the two outputs different?
As others have said, the reason for the empty space is because you asked it to print out str[3], which contains a space character.
Your second question seems to be asking why there's a difference between printing a char* (it prints the string) and int* (it just prints the address). char* is treated as a special case, it's assumed to represent a C-style string; it prints all the characters starting at that address until a trailing null byte.
Other types of pointers might not be part of an array, and even if they were there's no way to know how long the array is, because there's no standard terminator. Since there's nothing better to do for them, printing them just prints the address value.
1) because str[3] is a space so char * ptr = str+3 points to a space character
2) The << operator is overloaded, the implementation is called depending on argument type:
a pointer to an int (int*) uses the default pointer implementation and outputs the formatted address
a pointer to a char (char*) is specialized, output is formated as a null terminated string from the value it points to. If you want to output the adress, you must cast it to void*
The empty space is actually Space character after "LAB". You print the space character between "LAB" and "No 5".
Your second question: You see address, because ptr1 is actually address (pointer):
int *ptr1;
If you want to see it's first member (0), you should print *ptr1
Here is the code:
#include<iostream>
struct element{
char *ch;
int j;
element* next;
};
int main(){
char x='a';
element*e = new element;
e->ch= &x;
std::cout<<e->ch; // cout can print char* , in this case I think it's printing 4 bytes dereferenced
}
am I seeing some undefined behavior? 0_o. Can anyone help me what's going on?
You have to dereference the pointer to print the single char: std::cout << *e->ch << std::endl
Otherwise you are invoking the << overload for char *, which does something entirely different (it expects a pointer to a null-terminated array of characters).
Edit: In answer to your question about UB: The output operation performs an invalid pointer dereferencing (by assuming that e->ch points to a longer array of characters), which triggers the undefined behaviour.
It will print 'a' followed by the garbage until it find a terminating 0. You are confusing a char type (single character) with char* which is a C-style string which needs to be null-terminated.
Note that you might not actually see 'a' being printed out because it might be followed by a backspace character. As a matter of fact, if you compile this with g++ on Linux it will likely be followed by a backspace.
Is this a null question.
Strings in C and C++ end in a null characher. x is a character but not a string. You have tried to make it one.