Using Integer And Char Pointers in C++ or C? - c++

int *ab = (int *)5656;
cout << *ab; //Here appcrash.
int *ab;
*ab = 5656;
cout << *ab; //These block crashes the app too.
But i can get the hex value of content of pointer if i write this:
int *ab = (int *)5656;
cout << ab; //Output is hex value of 5656.
So i want to ask: * is a operator that brings the contents of pointer(?) but why in this(these) example(s) app crashes?
And i can use that operator if i change code into this:
int a = 5656;
int *aptr = &a;
cout << *aptr; //No crash.
And why dereference operator(*) brings the only first character of a char:
char *cptr = "this is a test";
cout << *cptr; // Here output = 't'
cout << cptr; // Here output = 'this is a test'

int *ab = (int *)5656;
cout << *ab; //Here appcrash.
In this case, you are setting the pointer ab to point at the address 5656. Do you know what's at this address? No you don't. You are telling the compiler to trust you that there is an int there. Then, when you dereference the pointer with *ab, you obviously find that there isn't an int there and you get undefined behaviour. In this case, your program crashes.
int *ab;
*ab = 5656;
cout << *ab;
In this case, you have an uninitialised pointer ab which you then dereference to assign 5656 to the int it points at. Since it's uninitialised, dereferencing it gives you undefined behaviour. Think of it this way. You haven't put an addres in ab so you don't know where it points. You can't just dereference it and hope it points at an int.
int a = 5656;
int *aptr = &a;
cout << *aptr;
This is fine because you know you have an int object with value 5656 and you know that aptr contains the address of that int object. It's perfectly fine to dereference aptr.
const char *cptr = "this is a test";
cout << *cptr; // Here output = 't'
cout << cptr;
(Your code was using a deprecated conversion to char*, so I changed it to a const char*.)
The string literal "this is a test" gives you an array containing const chars. However, it then undergoes array-to-pointer conversion giving you a pointer to its first element. Since each element is a const char, the pointer you get is a const char*. You then store this pointer in cptr.
So cptr points at the first element of the string. Dereferencing that pointer gives you that first element, which is just the first character of the string. So you output t.
The I/O library has special overloads that take const char*s and treat it as pointing to a string of characters. If it didn't, cout << cptr would just print out the address in cptr. Instead, these special overloads will print out the null-terminated array of characters that cptr is assumed to point to.

I think it's worth noting that the application crashes you are observing are due to the fact that it is very unlikely that your process (i.e. program) owns the memory at the location you specify: 5656.
Modern operating systems disallow access to memory allocated by other processes.
Imagine what a headache it would be if that we're not the case: one program could modify the data associated with another one!
The "access violation" message is a helpful hint that you're accessing memory that your process does not own.

is a operator that brings the contents of pointer(?)
No. * is a operator that brings the contents of memory which pointer point to.
Here:
int *ab = (int *)5656;
cout << *ab; //Here appcrash.
Pointer ab contains 5656. *ab tries to access memory which pointer ab point to => *ab tries to access memory at address 5656. Your program is not allowed to access memory at address 5656 because it is not allocated or read-only => app crashes.
And i can use that operator if i change code into this:
int a = 5656; int *aptr = &a; cout << *aptr; //No crash.
Here you allocate and initialize memory: int a = 5656;
Here you write address of previously allocated memory to pointer: int *aptr = &a;
Here you access memory which was previously allocated: *aptr (memory contains 5656).
You have right to access it => app doesn't crash.
And why dereference operator(*) brings the only first character of a char
Because char is not string, char is character. When you dereference pointer to char, you get char.
C has no built-in type for string. That's why it's common to use pointer to memory containing string. This pointer usually points to a first character of string: char * - pointer to character

Related

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 to point a pointer to a character

So i want to point a pointer to a character and then output the address put it outputs this weird thing: t+ a. Any help?
#include <iostream>
using namespace std;
int main() {
char a = 't';
char* p = &a;
cout << p;
return 0;
}
You are printing a char* type, which the cout tries to interpret as a string.
Print the value of the pointer (The address it points to) using:
cout << (void *)p;
-- OR --
cout << static_cast<void *>(p);
The problem is that char * is conventionally not just used as a pointer to a char, but a pointer to a null-terminated C-string instead. cout will then print all the characters pointed to by p until it finds a '\0', so you get to see the t and then it prints invalid memory which is undefined behavior which may crash or print garbage or something else.
The way to fix this is to use void * or maybe const void * instead which is just a pointer with an address but no type information attached. void *p = &a; would be one fix. void *p2 = p; and then using std::cout << p2; would be another. You can also use a cast as shown in the other answer, except you should be using a C++ cast like static_cast<const void*>(p) instead of a C cast like (void *)p because once you get used to them they become easier to read and reason about.
If you want address of the pointer, either cast it to void pointer
std::cout << (void *)p;
or use printf with %p option
printf("%p", p);
Otherwise it will be treated as null terminated string, which it is not.

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.

Operator precedence and pointer arithmetic

Given the following code:
void Allocate(int *p)
{
p = new int;
*p++ = 2;
}
int main()
{
int i = 10;
Allocate(&i);
std::cout << i << std::endl;
}
I'm a bit confised about the meaning of:
*p++ = 2;
The output is 10 and my reasoning as to why this is the case is that *p++ is a temporary therefore any assignment to it is lost at the end of the scope of Allocate(int *p).
Is this the case?
Thanks in adv!
On input to Allocate, p points to the variable i in the main
function.
The address of this variable then lost and replaced by the
new int.
The value of this int (which is uninitialized and so could
start as anything) is set to 2.
The p pointer is incremented.
The Allocate function returns at this point, leaking the int that was
allocated.
The value of i in the main function is unchanged,
because Allocate did not modify it.
when you pass the the address of i into Allocate, another (temp) pointer is created that points to i's address (i.e. passing by pointer). then that temp pointer is pointed to a new location (via new int). thus the value of i is left alone.
p = new int;
You're assigning p new memory to point to instead of what it was pointing to before. You then change this newly allocated memory and it's lost forever when the function ends, causing a memory leak. If you remove the allocation line, it should cause an output of 2. The ++ does nothing in this case. It just increments the pointer and returns the old value to dereference.
As soon as you enter Allocate, you assign p to point to a new block of memory, so it no longer points to i. Then you modify that new block of memory (which is then leaked when the method returns.) i is unaffected because you've moved that pointer before you set the pointed-to memory cell.
void Allocate(int **p)
{
*p = new int;
**p = 2;
}
int main()
{
int j = 10;
int *i = &j;
std::cout << i << std::endl;
Allocate(&i);
std::cout << i << std::endl;
}
Output is :
10
2
You need a pointer to pointer to change the address of the location being pointed to.

With or without an asterisk when incrementing pointer

In "void pointers" example in the tutorial on cplusplus.com, I try to compare like following. Why do we still need * in parenthesis? What is happening when no *?
void increase(void* data, int psize) {
if (psize == sizeof(char)) {
char* pchar;
pchar = (char*) data;
cout << "pchar=" << pchar << endl;
cout << "*pchar=" << *pchar << endl;
//++(*pchar); // increases the value pointed to, as expected
++(pchar); // the value pointed to doesn't change
} else if (psize == sizeof(int)) {
int* pint;
pint = (int*) data;
//++(*pint); // increases the value pointed to, as expected
++(pint); // the value pointed to doesn't change
}
}
int main() {
char a = 'x';
int b = 1602;
increase(&a, sizeof(a));
increase(&b, sizeof(b));
cout << a << ", " << b << endl;
return 0;
}
Update after accepting solution) I try to make clear what I didn't get, based on #Cody Gray's answer. The address of pchar is incremented to point to nonsense location. But because variable a in main is coutted instead of pchar, this cout still prints a value that somewhat makes sense (in this example it would be 'x').
The * operator dereferences the pointer.
Therefore, this code:
++(*pint)
increments the value pointed to by pint.
By contrast, this code:
++(pint)
increments the pointer itself, pint. This is why the value pointed to by the pointer doesn't change. You're not changing the value pointed to by the pointer, but rather the value of the pointer itself.
Incrementing a pointer will cause it to point to an entirely different value in memory. In this case, since you only allocated space for a single integer, it will point to a nonsense value.
When you make a cast from pointer to other pointer
char* pchar;
pchar = (char*) data;
you telling to compiler to process this memory as char pointer, in which you could perform pointer arithmetic to this variable. Therefore, you are not working with the value of the pointer just with pointer, that's is a memory address in which you are making the arithmetic.
To work with the value you need to use "*" or access to memory pointer by the char.