difference between int* and char* in c++ - 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.

Related

how character pointer could be used to point a string in c++?

First of all I am beginner in C++. I was trying to learn about type casting in C++ with strings and character pointer. Is it possible to point a string with a character pointer?
int main() {
string data="LetsTry";
cout<<(&data)<<"\n";
cout<<data<<"\n"<<"size "<<sizeof(data)<<"\n";
//char *ptr = static_cast<char*>(data);
//char *ptr=(char*)data;
char *ptr = reinterpret_cast<char*>(&data);
cout<<(ptr)<<"\n";
cout<<*ptr;
}
The above code yields outcome as below:
0x7ffea4a06150
LetsTry
size 32
`a���
`
I understand as ptr should output the address 0x7ffea4a06150
Historically, in C language strings were just a memory areas filled with characters. Consequently, when a string was passed to a function, it was passed as a pointer to its very first character, of type char *, for mutable strings, or char const *, if the function had no intent to modify string's contents. Such strings were delimited with a zero-character ((char)0 a.k.a. '\0') at the end, so for a string of length 3 you had to allocate at least four bytes of memory (three characters of the string itself plus the zero terminator); and if you only had a pointer to a string's start, to know the size of the string you'd have to iterate it to find how far is the zero-char (the standard function strlen did it). Some standard functions accepted en extra parameter for a string size if you knew it in advance (those starting with strn or, more primitive and effective, those starting with mem), others did not. To concatenate two strings you first had to allocate a sufficient buffer to contain the result etc.
The standard functions that process char pointers can still be found in STL, under the <cstring> header: https://en.cppreference.com/w/cpp/header/cstring, and std::string has synonymous methods c_str() and data() that return char pointers to its contents, should you need it.
When you write a program in C++, its main function has the header of int main(int argc, char *argv[]), where argv is the array of char pointers that contains any command-line arguments your program was run with.
Ineffective as it is, this scheme could still be regarded as an advantage over strings of limited capacity or plain fixed-size character arrays, for instance in mid-nineties, when Borland introduced the PChar type in Turbo Pascal and added a unit that exported Pascal implementations of functions from C's string.h.
std::string and const char* are different types, reinterpret_cast<char*>(&data) means reinterpret the bits located at &data as const char*, which is not we want in this case.
so assuming we have type A and type B:
A a;
B b;
the following are conversion:
a = (A)b; //c sytle
// and
a = A(b);
// and
a = static_cast<A>(b); //c++ style
the following are bit reinterpretation:
a = *(A*)&b; //c style
// and
a = *reinterpret_cast<A*>(&b); //c++ style
finally, this should works:
int main() {
string data = "LetsTry";
const char *ptr = data.c_str();
cout<< ptr << "\n";
}
bit reinterpretation is sometimes used, like when doing bit manipulation of a floating point number, but there are some rules to follow like this one What is the strict aliasing rule?
also note that cout << ptr << "\n"; is a specially case because feeds a pointer to std::cout usually output the address that pointer points to, but std::cout treats char* specially so that it output the content of that char array instead
In C++, string is class and what you doing is creating a string object. So, to use are char * you need to convert it using c_str()
You can refer below code:
std::string data = "LetsTry";
// declaring character array
char * cstr = new char [data.length()+1];
// copying the contents of the
// string to char array
std::strcpy (cstr, data.c_str());
Now, you can get use char * to point your data.

Why does the following program - passing c string to function - not produce the desired output?

I have a simple question C++ (or C).
Why does the following program, passing c string to function, not produce the desired output?
#include <cstdio>
#include <cstring>
void fillMeUpSomeMore( char** strOut )
{
strcpy( *strOut, "Hello Tommy" );
}
int main()
{
char str[30];
//char* strNew = new char[30];
fillMeUpSomeMore( (char**) &str ); // I believe this is undefined behavior but why?
//fillMeUpSomeMore( (char**) &strNew ); // this does work
std::printf( "%s\n", str );
//std::printf( "%s\n", strNew ); // prints "Hello Tommy"
//delete[] strNew;
}
All I'm doing is passing the address of the char array str to a function taking pointer to pointer to char (which after the explicit conversion should be just fine).
But then the program prints nothing.
However this will work with the strNew variable that has been dynamically allocated.
I know that I shouldn't be doing this and be using std::string instead. I'm only doing this for study purposes. Thanks.
I'm compiling with g++ & C++17 (-std=c++17).
char ** is a pointer to a pointer to a character. This means, if it is not a null pointer, it should be the address of some place in memory where there is a pointer.
char str[30] defines an array of 30 char. &str is the address of that array. There is no pointer there, just 30 char. Therefore, &str is not a char **.
So (char**) &str is bad. It tells the compiler to treat the address of the array as if it were the address of a pointer. That is not going to work.
If you instead use char *strNew = new char[30];, that says strNew is a pointer, which is initialized with the address of the first char of an array of 30 char. Then, since strNew is a pointer, &strNew is the address of a char *, so it is a char **, and (char **) &strNew is not wrong.
Generally, you should avoid casts and pay attention to compiler warnings. When the compiler tells you there is a problem with types, work to understand the problem and to fix it by changing the types or expressions involved, rather than by using a cast.
Why does the following program, passing c string to function, not produce the desired output?
When you do a cast like (char **), you aren't specifying which of const_cast, static_cast and / or reinterpret_cast you want, but instead whichever are neccessary to get from your expression's type to the target type.
The expression &str has type char (*)[30], so you are doing a reinterpret_cast to an unrelated type.
The expression &strNew has type char **, so you don't need a cast at all.
When you are writing C++ you should never use a C style cast. You should instead use whichever of the C++ casts (static_cast, const_cast, reinterpret_cast) that you intend.

How to: Typecasting Pointers on 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);

Weird output when printing char pointer from struct

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.

Why char *x not char x?

I've a code
#include <iostream>
using namespace std;
void foo(char *name){ // ???
cout << "String: " << name << endl;
}
int main(){
foo("Hello");
return 0;
}
I don't know why I use "char name" won't work. Please help.
Cheers,
char a is just a single character, while char* is a pointer to a sequence of characters - a string.
When you call foo("Hello"), you pass in a string literal (strictly speaking an array of chars) which is convertible to a pointer to char. Therefore foo must accept char* rather than char because otherwise the types wouldn't match.
char name is a single character
char* name is a pointer to a character in heap and if allocated correctly, can be an array of characters.
A string can be represented as an array of char(s). You can use the char * pointer to refer to that string.
You could use char name with foo('c'), because that's a char.
Because a simple char is just one character, like 'c','A','0',etc.. char* is a pointer to a region in memory, where one or more chars are stored.
In C and C++ strings are quite often represented as an array of characters terminated by the null character.
Arrays in C and C++ are often represented as a pointer to the first item.
Therefore a string is represented as a pointer to the first character in the string and that is what char *name means. It means name is a pointer to the first character in the string.
You might want to read up a bit on pointers, arrays and strings in C/C++ as this is fundamental stuff!
char refers to a single character. char* is a pointer to an address in memory that contains a 1 or more characters (a string). If you are using C++, you might consider using std::string instead as it may be slightly more familiar.