How to: Typecasting Pointers on c++ - c++

I am learning typecasting.
Here is my basic code, i dont know why after typecasting, when printing p0, it is not showing the same address of a
I know this is very basic.
#include <iostream>
using namespace std;
int main()
{
int a=1025;
cout<<a<<endl;
cout<<"Size of a in bytes is "<<sizeof(a)<<endl;
int *p;//pointer to an integer
p=&a; //p stores an address of a
cout<<p<<endl;//display address of a
cout<<&a<<endl;//displays address of a
cout<<*p<<endl;//display value where p points to. p stores an address of a and so it points to the value of a
char *p0;//pointer to character
p0=(char*)p;//typecasting
cout<<p0<<endl;
cout<<*p0;
return 0;
}

When you pass a char * pointer to the << operator of std::cout, it prints the string that the pointer points to, not the address. It's the same behavior as the following code:
const char *str = "Hello!";
cout << str; // Prints the string "Hello!", not the address of the string
In your case, p0 doesn't point to a string, which is why you're getting unexpected behavior.

The overload of operator<<, used with std::cout and char* as arguments, is expecting a null-terminated string. What you are feeding it with, instead, is a pointer to what was an int* instead. This leads to undefined behavior when trying to output the char* in cout<<p0<<endl;.
In C++, is often a bad idea to use C-style casts. If you had used static_cast for example, you would have been warned that the conversion your are trying to make does not make much sense. It is true that you could use reinterpret_cast instead, but what you should be asking yourself is: why am I doing this? Why am I trying to shoot myself in the foot?
If what you want is to convert the number to string, you should be using other techniques instead. If you just want to print out the address of the char* you should be using std::addressof:
std::cout << std::addressof(p0) << std::endl;

As others have said cout is interpreting the char* as a string, and not a pointer
If you wanted to prove that the address is the same whatever type of pointer it is then you can cast it to a void pointer
cout<<(void*)p0<<endl;
In fact you get the address for pretty much any type other than char&
cout<<(float*)p0<<endl;
To prove to yourself that a char* pointer would have the same value use printf
printf("%x", p0);

Related

Pointers with character array variables

I'm learning C++ and was understanding pointers and created the following code
#include<string>
using namespace std;
int main()
{
char s[100] = "Today is a rainy day";
cout<<s[0]<<endl;
char *p;
p = s;
cout <<s<<endl;
cout<<p<<endl;
cout<<*p<<endl;
}
In this code, I assumed that as s points to the starting address of the array, printing the pointer p will give me the address and *p will give me the first element of the array.
My output was of the form
T
Today is a rainy day
Today is a rainy day
T
Here, p and s both print out the complete character array which I did not understand, also using the *p was printing out the first element even though p was now just an array.
How do the pointers function when we use them in arrays like this is what I would like to understand.
The difference between a pointer and an array exists only at compile time.
At runtime they are the same, decayed to pointers.
For an array at compile time you can find its dimensions, and use those as parameters in template code. See std::is_array, std::extent, etc.
When you dereference either the array or pointer, you end up with a char. This prints that char, as you might have expected.
However, when you provide a char* (which is what you get with both the array and pointer case, as the array decays to a pointer here), the overload of the operator<< for char* is called instead.
This overload treats any char* it sees as a C-string, which is why you see it printed out as such.

Initialization of pointers in c++

I need to clarify my concepts regarding the basics of pointer initialization in C++. As per my understanding, a pointer must be assigned an address before putting some value using the pointer.
int *p;
*p=10; //inappropriate
cout << *p <<"\n";
This would probably show the correct output (10) but this may cause issue in larger programs since p initially had garbage address which can be anything & may later be used somewhere else in the program as well.So , I believe this is incorrrect, the correct way is:
int *p;
int x=10;
p=&x; //appropriate
cout << *p <<"\n";
My question is, if the above understanding is correct, then does the same apply on char* as well?:
const char *str="hello"; // inappropriate
cout << str << "\n";
//OR
const string str1= "hello";
const char str2[6] ="world";
const char *str=str1; //appropriate
const char *st=str2; //appropriate
cout << str << st << "\n";
Please advice
Your understanding of strings is incorrect.
Lets take for example the very first line:
const char *str="hello";
This is actually correct. A string literal like "hello" is turned into a constant array by the compiler, and like all arrays it can decay to a pointer to its first element. So what you are doing is making str point to the first character of the array.
Then lets continue with
const string str1= "hello";
const char *str=str1;
This is actually wrong. A std::string object have no casting operator defined to cast to a const char *. The compiler will give you an error for this. You need to use the c_str function go get a pointer to the contained string.
Lastly:
const char str2[6] ="world";
const char *st=str2; //appropriate
This is really no different than the first line when you declare and initialize str. This is, as you say, "appropriate".
About that first example with the "inappropriate" pointer:
int *p;
*p=10; //inappropriate
cout << *p <<"\n";
This is not only "inappropriate", this leads to undefined behavior and may actually crash your program. Also, the correct term is that the value of p is indeterminate.
When I declare a pointer
int *p;
I get an object p whose values are addresses. No ints are created anywhere. The thing you need to do is think of p as being an address rather than being an int.
At this point, this isn't particularly useful since you have no addresses you could assign to it other than nullptr. Well, technically that's not true: p itself has an address which you can get with &p and store it in an int**, or even do something horrible like p = reinterpret_cast<int*>(&p);, but let's ignore that.
To do something with ints, you need to create one. e.g. if you go on to declare
int x;
you now have an int object whose values are integers, and we could then assign its address to p with p = &x;, and then recover the object from p via *p.
Now, C style strings have weird semantics — the weirdest aspect being that C doesn't actually have strings at all: it's always working with arrays of char.
String literals, like "Hello!", are guaranteed to (act1 like they) exist as an array of const char located at some address, and by C's odd conversion rules, this array automatically converts to a pointer to its first element. Thus,
const char *str = "hello";
stores the address of the h character in that character array. The declaration
const char str2[6] ="world";
works differently; this (acts1 like it) creates a brand new array, and copies the contents of the string literal "world" into the new array.
As an aside, there is an obsolete and deprecated feature here for compatibility with legacy programs, but for some misguided reason people still use it in new programs these days so you should be aware of it and that it's 'wrong': you're allowed to break the type system and actually write
char *str = "hello";
This shouldn't work because "hello" is an array of const char, but the standard permits this specific usage. You're still not actually allowed to modify the contents of the array, however.
1: By the "as if" rule, the program only has to behave as if things happen as I describe, but if you peeked at the assembly code, the actual way things happen can be very different.

difference between int* and char* in c++

#include <iostream>
using namespace std;
int main() {
int * a[5];
char * b[5];
cout<<a[1]; // this works and prints address being held by second element in the array
cout<<b[1]; // this gives run time error . why ?
return 0;
}
Can anyone please explain to me cout<<b[1] gives run-time error ?
Shouldn't both int and char array behave similar to each other ?
Because IOStreams are designed to treat char* specially.
char* usually points to a C-string, so IOStreams will just assume that they do and dereference them.
Yours don't.
As others have said, iostream formatted output operators consider char* to point to C-style string and attempt to access this string.
What others have not said so far, is that if you are interested in the pointer, you need to cast the pointer in question to void*. For example:
std::cout << static_cast<const void*>(buf[1]);
An output stream such as cout gives special consideration to char * that it does not give to other pointers. For pointers other than char *, it will simply print out the value of the pointer as a hexadecimal address. But for char *, it will try to print out the C-style (i.e. null terminated array of char) string referred to by the char *. Therefore it will try to dereference the char pointer, as #AlexD points in the comment to your post.
C++ (inheriting it from C) treats character pointers specially. When you try to print a[1] of type int* the address is printed. But when you try to print b[1] of type char* the iostream library - following the rest of the language - assumes that the pointer points to the first character of zero-terminated string of characters. Both your output statements are initialised behaviour, but in the case of char* crash is much more likely because the pointer is dereferenced.

Returning base address in C(Pointers)

I am learning pointers and i tried this following program
#include <iostream>
#include <cstdlib>
#include <cstdio>
using namespace std;
char* getword()
{
char*temp=(char*)malloc(sizeof(char)*10);
cin>>temp;
return temp;
}
int main()
{
char *a;
a=getword();
cout<<a;
return 0;
}
To my level of understanding, a is a pointer to a character, and in the function getword() I returned temp which I think the base &temp[0]. I thought that the output would be the first character of the string I enter, but I got the entire string in stdout. How does this work?
In the tradition of C, a char* represents a string. Indeed, any string literal in your program (e.g. "hello") will have a type of const char *.
Thus, cout::operator<<( const char * ) is implemented as a string-output. It will output characters beginning at the address it is given, until it encounters the string terminator (otherwise known as null-terminator, or '\0').
If you want to output a single character, you need to dereference the pointer into a char type. You can choose one of the following syntaxes:
cout << *a; // Dereference the pointer
cout << a[0]; // Use array index of zero to return the value at that address
It should be noted that the code you provided isn't very C++ish. For starters, we generally don't use malloc in C++. You then leak the memory by not calling free later. The memory is uninitialised and relies on cin succeeding (which might not be the case). Also, you can only handle input strings of up to 9 characters before you will get undefined behaviour.
Perhaps you should learn about the <string> library and start using it.
It's true that char* "points to a character". But, by convention, and because with pointers there is no other way to do so, we also use it to "point to more than one character".
Since use of char* almost always means you're using a pointer to a C-style string, the C++ streams library makes this assumption for you, printing the char that your pointer points to … and the next … and the next … and the next until NULL is found. That's just the way it's been designed to work.
You can print just that character if you like by dereferencing the pointer to obtain an actual char.
std::cout is an overloaded operator and when it receives a char * as an operand then it treats it as a pointer to c style string and it will print the entire string.
If you want to print the first character of the string then use
cout << *a;
or
cout << a[0];
In your code, std::cout is an ostream and providing a char* variable as input to operator<< invokes a particular operator function overload to write characters to the ostream.
std::ostream also has a operator overload for writing a single character to itself.
I'm assuming you now know how to dereference a char* variable, but you should be using std::string instead of an unsafe char* type.
Here is the correct code
#include <stdio.h>
#include <stdlib.h>
char* getword()
{
char*temp=(char*)malloc(sizeof(char)*10);
scanf("%s",temp);
return temp;
}
int main()
{
char *a;
a = getword();
int currChar = 1;
printf("%c",*(a + currChar)); //increment currChar to get next character
return 0;
}

strange behaviour of assigning char array to single char

// example: class constructor
#include <iostream>
#include <string>
class Test{
public:
char* getColor(){
return color;
}
private:
char color[5] = "Blau";
};
int main () {
Test s;
char *myChar = s.getColor();
std::cout << myChar;
return 0;
};
I don't really understand how this actually returns "Blau" instead of just B or something else.
What I'm doing is assigning the starting pointer if a char array to a single char pointer.
I'd really like to understand why this happens like this. Maybe it's because of std::cout getting all values of that type? So instead of "B" it says "Blau"
There is no difference between a pointer to a single object and a pointer to the first element of an array. It's up to the programmer to know how it should be interpreted; or to use friendlier types like std::string.
When you stream a char* with <<, it assumes that it's the pointer to the first element of a zero-terminated C-style string, and prints all the characters it finds, starting from that one, until it finds one with a zero value.
myChar is not a single char but a pointer to such (and you can always do pointer-arithmetic / indexing instead of straight dereferencing).
And operator<< has an overload for ostream&+char*, to output it as a pointer to a 0-terminated string.
So, not really any surprise.
Array in c++ is the const pointer to first element of data block. Therefore your color variable is the pointer.