confusion of char* str="ab", str and &str - c++

I am learning pointer and this is my code. I defined a pointer to char (string actually) *str and a pointer to int *a, they are defined in the same way. I thought both str and a should be an address, but when I tried to output str and &str, a and &a, I found str is not an address, it is the string. What is the difference between char *str and int *a in terms of the type of str and a? Thank you.
#include<iostream>
#include<string>
using namespace std;
int main()
{
char *str = "FA";
cout << "str: " << str << endl;
cout << "&str: " << &str << endl;
int b = 5;
int *a = &b;
cout << "a: " << a << endl;
cout << "&a: " << &a << endl;
}
this is output:
str: FA
&str: 0x7fff5a627280
a: 0x7fff5a62727c
&a: 0x7fff5a627288

Well, this comes down to C semantics. A string is not a type defined in C. char is the type of a single character. In order to handle strings in C, by convention a pointer to char means a string that starts at the position this pointer points to and ends at the first 0 byte.
To make that clear:
char *str = "ABC";
"translates" to something like
const char <nosymbol>[4] = {'A', 'B', 'C', '\0'};
char *str = &(<nosymbol>[0]);
C++ knows about this special meaning of a char * and so, the << operator will, following the principle of least surprise for C programmers, take char * as a string.

The << operator for streams has an overload for char * that outputs a C-style string. This is usually what you want, but if it's not what you want, you can use reinterpret_cast<void*> or addressof.

Related

How do I print const char?

#include <iostream>
using namespace std;
int main() {
int age = 20;
const char* pDept = "electronics";
cout << age << " " << pDept;
}
The above code is normal.
Why shouldn't I use cout << *pDept instead of cout << pDept above?
Both of them are legal in C++. Which one to use depends on what you want to print.
In your case, pDept is a pointer that points to a char in memory. It also can be used as a char[] terminated with \0. So std::cout << pDept; prints the string the pointer is pointing to.
*pDept is the content that pDept points to, which is the first character of the string. So std::cout << *pDept; prints the first character only.

char * point to element not the address

void reverse(char * str){
char * end = str;
cout << "str" << str << endl;//ABCDE
cout << "end" << end << endl;//ABCDE
char tmp;
if(str){
while(*end){++end; cout << end << endl;}//ABCDE-->BCDE-->CDE-->DE-->E--> NULL
--end;//end=E
cout <<"--end" << end << endl;
while(str<end){// do swap
tmp = *str;//*str = str[0]
*str++ = *end;//*end = last ele in str[]
*end-- = tmp;
}
}
}
My input is
char test[] = "ABCDE";
cout << test << endl; //ABCDE
reverse(test);
cout << test << endl; //EDCBA
I am feeling not good about the pointer, since c++ primer book says char* pointer to the first element of an array, but when I output the pointer end, it is the content of an array not the address.
Also, reverse(test), I mean to give the address of the first element in an array to the pointer, but it turns out give the whole elements to the pointer.
A char* variable is a pointer to a char. A char[] is an array of char. Now, an array of char can be accessed through a pointer, and for char* it is commonly used for string processing (it's used although for other types, but for char it's much more common).
char test[6] = "ABCDE";
char *start = &test[0]; // will point on A
Accessing the array with the pointer can be done with pointer arithmetic:
char *end = start + 5; // equivalent to char *end = &test[5]
Now when you do:
cout << test;
or
cout << start;
It's actually calling an overload of operator<< that takes a const char*. What this operator does is that it print char starting from the pointer passed until it reaches a null char ('\0').
If you want to print the address contained in the pointer and not the string, you have to cast it to void*:
cout << static_cast<void*>(start);
std::cout is overloaded to print strings for char* .
Try:
char *test = "ABCDE";
std::cout << (void *) test << std::endl;

C++ reinterpret_cast object to string and back

I just discovered reinterpret_cast in C++ and I am trying to learn more about it. I wrote this code:
struct Human{
string name;
char gender;
int age;
Human(string n, char g, int a) : name(n), gender(g), age(a) {}
};
int main()
{
Human h("John", 'M', 26);
char* s = reinterpret_cast<char*>(&h);
Human *hh = reinterpret_cast<Human*>(s);
cout << hh->name << " " << hh->gender << " " << hh->age << endl;
}
It works pretty well, exactly as expected. Now I want convert the char * to an std::string and then from this string get back the Human object:
int main()
{
Human h("John", 'M', 26);
char* s = reinterpret_cast<char*>(&h);
string str = s;
Human *hh = reinterpret_cast<Human*>(&str);
cout << hh->name << " " << hh->gender << " " << hh->age << endl; // prints wrong values
}
Does anyone have an idea to overcome this ?
Thank you.
In your second program when you do
string str = s;
you create a completely new object that is totally unrelated to the pointer s. Getting the address from str will give you a pointer to str, and not the "string" it contains.
Also, using reinterpret_cast is a way to tell the compiler "I know what I am doing", and if you don't actually know what's happening then you will undoubtedly march into the territory of undefined behavior which is what will happen when you try to initialize str with the "string" pointed to by s, since it's not really a string.

Printing C++ int pointer vs char pointer

When I run the following code:
int i[] = {1,2,3};
int* pointer = i;
cout << i << endl;
char c[] = {'a','b','c','\0'};
char* ptr = c;
cout << ptr << endl;
I get this output:
0x28ff1c
abc
Why does the int pointer return the address while the char pointer returns the actual content of the array?
This is due to overload of << operator. For char * it interprets it as null terminated C string. For int pointer, you just get the address.
The operator
cout <<
is overload 'char *' so it knows how to handle it (in this case, printing all chars till the end one).
But for int is not, so it just prints out the 'memory address'
A pointer to char is the same type as a string literal. So for the sake of simplicity, cout will print the content of the char array as if it was a string. So when you are doing this:
cout << "Some text" << endl;
It does not print the address, the same way as your code is doing.
If you want to pring the address, cast it to size_t
cout << reinterpret_cast<size_t>(ptr) << endl;

Resolving C++ "The instruction at "x" referenced memory at "y"

I have the following program which is giving run time error:
*The instruction at "x" referenced memory at "y"
The memory could not be written.*
Code:
int main() {
char *str1 = "Rain";
char *&str2 = str1;
cout << str1 << str2 << endl;
*str1 = 'M';
cout << str1 << str2 << endl;
//Here the error happens
*str2 = 'P';
cout << str1 << str2 << endl;
return 0;
}
What is the cause of this error.
The problem is that a string literal is technically a 'char const pointer'. Reading right to left a pointer to unmodifiable characters. Because of backward comparability with 'C' this can be auto cast to 'char pointer' by the compiler. This does not mean that the underlying type has changed and thus modifying the underlying const object is undefined behavior.
char *str1 = "Rain"; // Lie this is not a char*
char const* str9 = "Rain"; // This is the real type.
// String lieterals => "XXXXX" are char const*
If you want to modify the string what you need to do is declare an array.
char str6[] = "Rain";
str6[0] = 'M';
*str6 = 'P';