Char array vs Int array [duplicate] - c++

This question already has answers here:
Why does cout print char arrays differently from other arrays?
(4 answers)
Closed 7 years ago.
I have the following problem:
int a[2][2]={{1,2},{3,4}};
cout<<a[1]; //the output is 0x29ff18 , which is an address
--------------------------------------------------------------------
char b[][6]={"hello","there","now"};
cout<<b[1]; //the output is there, which is value of b[1]
I am wondering why b[1] will not give an address like a[1]...
thanks!

The basic difference between in a character array and an integer array is the terminating null character : \0
If you declare your character array like this :
char b[] = {'h','i'};
Then your cout statement fails to identify what to do, and will give strange output. But as soon as you do :
char b[] = {'h','i','\0'};
or
char b[] = "hi";
Your cout works fine. This is because in first, you are explicitly adding a null character at the end, and in the second, it gets added automatically by the compiler.
And for the array, and array declared as a[] or a[][], the compiler stores the address of the first element of the array in variable a, so you get the address of the first element in case of an non-character array.
Refer to this link for more info :
What is the difference between int and char arrays?

The type of v determines what cout << v prints.
One case you have int array, other case you have char array. Cout by definition prints a char array different than int array. Just the way it is. As bjorne.

Related

Confusion over char* array elements access [duplicate]

This question already has answers here:
cout << with char* argument prints string, not pointer value
(6 answers)
Closed 4 years ago.
I am learning c++ and encountered this:
#include<iostream>
using namespace std;
int main(){
const char *a[] = {"ge","hy"};
cout<<a<<" "<<&a[1]<<endl;
cout<<a[0]<<" "<<a[1];
return 0;
}
The output is :
0x7fff54e71830 0x7fff54e71838
ge hy
I tried to understand the code.
Here is my understanding:
a is an array of character pointers which means that each element of the array is a char pointer.
Now, since every element is a pointer then it should store the address of "ge" and "hy" respectively.
-----------------------------------
a = | 0x7fff54e71830 | 0x7fff54e71838 |
-----------------------------------
Now when I write a[0] and a[1] then why does it print the ge hy and not the memory address of them because the array a stores their address and not their actual value.
I am sure that I'm going wrong somewhere because the output is not as expected. Kindly, correct me here.
The standard library provides an overloaded operator<<(std::ostream&, const char*) for printing C-style strings that prints the string pointed to rather than the value of the pointer itself. That overload is a better match than the operator<<(std::ostream&, void*) overload that prints the address stored in a pointer.
If you want to print the value of the pointer, add a cast to void*:
std::cout << static_cast<void*>(a[0]) << ' ' << static_cast<void*>(a[1]) << '\n';
Live Demo

cannot convert char* to int* in assignment c++ [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
C++ implicitly converts char to int (a larger data type than char) in an expression, which means the following runs without a compile time error:
char a = 'a';
int b = a;
cout << b << endl;
// output
97
Why does the following then throw a compile time error:
char a = 'a';
char* str = &a;
int* ptr;
ptr = str;
Since pointers are of a fixed size (depending on 32/64 bit OS) irrespective of data type they are pointing to, please help me understand why this conversion is illegal.
"Since pointers are of a fixed size" the problem is not the size of the pointer, but the pointed type, a char is not an int, so a char * is not an int *
If you do after *str = <value> all is ok because you only change one byte, but *ptr = <value> will write into more than one byte with unexpected consequences etc
What you want to do is undefined behavior.
You start with a char and get a pointer to it. That's fine. For instance, the pointer could be 0x01. Then you say, actually that pointer to 1 byte, let's make it to a pointer to 4 bytes (32bits assumption for an int).
Obviously, that cannot work. Where are the other 3 bytes coming from?
Then, let's say that it does work. You get alignment issues, because the int should be aligned on 4bytes boundaries, and your pointer is not.
Hence lots and lots of issues what you want to do:
access to inexistent memory
bad memory access (alignement).
This cannot work.
When you assign a char to an int, you create a new variable, a new place with 4 bytes that can receive your data. Here, you don't create a new variable that can hold that data.
You had stated:
C++ implicitly typecasts char to int (a larger data type than char) in an expression, which means the following runs without a compile time error:
char a = 'a';
int b = a;
cout << b << endl;
Output:
97
Then you asked:
Why does the following then throw a compile time error:
char a = 'a';
char* str = &a;
int* ptr;
ptr = str;
In your first example, you declare a char variable named a and assign it the character 'a'. Then you declare an int variable named b and assign it the value of a. Then you call cout on b. This gives a value of 97 which is expected.
What is happening here is the compiler will implicitly cast the value of the char a to an integer. The reason you are seeing the value 97 is because this is the assigned ASCII code for the lower case a. The variable sizes here don't matter.
In your second example where you begin to ask about your compiler error is as follows:
You declare the same char variable as above and assign it the same character value a.
This time you create a pointer to a char and name it str and assign it to the address of a. str now points to a. Next you created a pointer to an int named ptr, then you try to assign str to ptr. Yes all pointers have the same size in memory, but what you are failing to understand here, is how pointer addressing works. Since you are not using new & delete respectively these pointers are on the stack. So on my machine I have ran this code:
#include <iostream>
int main() {
char a = 'a';
char* str = &a;
std::cout << &str << '\n'; // print str's address
int* ptr; // don't assign ptr to anything...
std::cout << &ptr << '\n'; // print ptr's address
}
On my machine the output is:
003BFC34 // this is the stack address of str
003BFC28 // this is the stack address of ptr
Yes both pointers themselves typically take up 4 bytes of memory on a 32bit machine. However, str is pointing to a char type of 1 byte, and ptr is pointing to a int type of 4 bytes on a 32bit machine.
So when you try to assign one pointer to another; this will only work when the pointer types are of the same type! Otherwise, you will either have a compiler error in your case or UB.
Your assumption in the first case is that the char became an int and that is not the case. What happens in your first case is it is taking the value that is represented by 1 byte and implicitly converts it to an integer type that takes 4 bytes and the integer representation of the lowercase a is the ASCII value of 97.
Therefore your 2nd case will not compile:
int main() {
char a = 'a';
char* str = &a;
int* ptr = str; // fails to compile.
return 0;
}
However, there is a way to convert pointers from one type to another
int main() {
char a = 'a';
char* str = &a;
int* ptr = (int*)(str); // C Style Cast - Will Compile!
int* ptr = reinterpret_cast<int*>( str ); // This will compile!
return 0;
}
When you assign int value to char variable and vice versa the compiler do the casting implictly.
But if you assign pointer of type int to address of char variable, it's illegal, because it's int pointer it should point to int variable.
The other direction is the same, char pointer should point to char integer.
The reason is because in memory char represented in one byte while int represented with four bytes.
It's important for memory allocating and freeing.

How do I correctly work with char pointer to array in C++?

I am trying to pick up my C++; I have basic understanding of pointers and references; but when it comes to char pointer to array, it seems nothing works for me.
I have a small piece of codes here (omitted include and namespace statements), I have included my questions as comments below:
I have gone through at least 5 other questions on SO to try to understand it; but those answers didn't the answer I expected and to the extent that could help understand the actual issue there.
Could you kindly explain the problems I commented below with a bit of depth from the surface (so please don't dive into it directly)?
int main(){
// 1 this is a char pointer to a char;
char * c = new char;
*c ='A';
cout << c << endl; // this gives me memory address;
cout << *c << endl;// this gives me the value in the memory address;
// 2 this is a char array initialised to value "world";
char d[6] = "world";
cout << d[0] << endl; // this gives me the first element of char array;
// 3 this is char pointer to char array (or array of char pointers)?
char * str = new char[6];
for(int i=0;i<6;i++){ //
str[i]=d[i]; // are we assigning the memory address (not value) of respective elements here?
} // can I just do: *str = "world"; what's the difference between initialising with value
// and declaring the pointer and then assign value?
char * strr = "morning";
char b[6] = "hello";
cout << b << endl;
cout << (*str)[i] << endl; // why? error: subscripts requires array or pointer type
cout << str[1] << endl;
cout << (*strr)[1] << endl; // why? error: subscripts requires array or pointer type
}
// 1 this is a char pointer to a char;
Right.
// 2 this is a char array initialised to value "world";
Right, "world\0" is created by the compiler and is put in the read-only memory area of the program. Note that this is called a string literal. Then the string is copied over to the char array d.
// 3 this is char pointer to char array (or array of char pointers)?
That's a char pointer yes, a pointer to a single char.
// are we assigning the memory address (not value) of respective
elements here?
No, you're assigning the values of the elements. This is allowed because str[i] is the same as *(str + i) so you can use the same "array style" access with the pointer str. You're looping over the individual chars you have allocated with new and are assigning them the value of the chars in the char array d.
// why? error: subscripts requires array or pointer type
Because you already dereference str (which is pointing at the start of the 6 element char array) with * which gives you a char, then you try to use that char like an array with [1] which makes no sense. *str would give you 'w' (the first element). And str[1] would give you *(str + 1) which is 'o' (the second element), don't double up.
A small-big side note, string literals are of type const char[], not char[], they're placed in read only memory and thus they can not be altered by the program (don't write to them).
char * strr = "morning";
This is very very bad, it treats a const char[] as a char[], this has been deprecated in the standard for a while now and according to the current standard this is even illegal, yet compilers still allow it for some reason.
Because compilers allow this you could get some nasty situations like trying to modify the string literal:
char * strr = "morning";
strr[0] = 'w'; // change to "worning"
This will attempt to write to read-only memory, which is undefined behaviour and will probably/hopefully get you a segmentation fault. Long story short, use the appropriate type to have the compiler stop you before the code reaches runtime:
const char * strr = "morning";
side side note : don't forget to delete anything you allocated with new.

Why char array and int array get printed as different things? [duplicate]

This question already has answers here:
Why does cout print char arrays differently from other arrays?
(4 answers)
Closed 7 years ago.
int main ()
{
int intarr [5] = {1,6,7,9,3);
char charr [7] = "Avneet";
std::cout << intarr << "\n";
std::cout << charr << "\n";
return 0;
}
The first line this program prints is a memory address and second line, the whole string (Avneet). What's making the difference? One more question. In the int case, the address I get is what? The address of the entire array or just the address of the first element of that array.
std::basic_ostream<> has overloads of operator<< for char const* and signed/unsigned versions that expect a C-style zero-terminated string.
And void const* overload which is used for any other pointer types and outputs the address.
The std::cout operator << is overloaded for const char* in such a way that the string that it points to is printed out. This is not the case for int* arguments.
When an array is passed (by value) as an argument to a function the argument decays to a pointer to the first element in the array and that is why you get the behaviour you are seeing - the char array argument decays to char* and the cout operator << overload prints the string.
In the int* case there is no overload and so you just see the address of the first element of your int array printed.
I would say that when creating a char[7] it acts like a String of 7 characters. When printing that will not show its address but the value.
On the other hand the int array is an object which holds some primitives. When printing it you will simply see that objects address. You need a for loop to print each of the arrays elements.

char array[] weird output [duplicate]

This question already has answers here:
cout << with char* argument prints string, not pointer value
(6 answers)
Closed 7 years ago.
char a[] = {'k','l','m'};
cout << a << endl;
int b[] = {1,2,3};
cout << b << endl;
I run the above C++ code and here's the output:
klm
0x22fe00
I observe that char is the only primary type that has this behavior. Why this is happening? Are there any specialities of the char type?
The name of an array often evaluates to the address of its first element. The standard output stream interprets character pointers as strings, and prints the data as a string. For integers, there is no such interpretation so you see the actual pointer value.
The char[] is essentially how C and C++ treat strings of characters. The operator<< has been overloaded for the char[] to print out the values of the char array. On the other hand, arrays are essentially treated as constant pointers to their base element:
const int* p = &b[0];
Therefore, when you do cout << b << endl, you're actually printing out the base address of the array. That's why you get the hex number.