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.
Related
I apologize in advance for the silliness of this question. But I couldn't find the way of understanding this outcome. I'm trying to figure out what the pointer really is in C++. Following is just a simple code printing an address in different ways.
int a = 15000;
char *b = reinterpret_cast<char*>(a); //equivalent of char *b = (char *)a
int *m = &a;
//(1)
printf("&a:%p\n",&a); //0x7fff5fbff878
printf("&*m:%p\n",&*m); //0x7fff5fbff878
printf("m:%p\n",m); //0x7fff5fbff878
//(2)
printf("a:%p\n",(int*)a); //0x3a98
printf("&*b:%p\n",&*b); //0x3a98
printf("b:%p\n",b); //0x3a98
printf("*m:%p\n",(int*)*m); //0x3a98
printf("&b:%p\n",&b); //0x7fff5fbff870
printf("&m:%p\n",&m); //0x7fff5fbff868
//(3)
std::cout << "b:" << b << std::endl; //error: Segmentation fault: 11
So the question is
why the address of (1) and (2) are different
why the size(length of address) of (1) and (2) are different
what happened when an int is cast to a char*
how 'b' could contain an address of 'a'
why the error (3) has occurred while 'printf("b:%p\n",b)' is working.
why the address of (1) and (2) are different
Because in the first example (1), you use the & address of operator, which gives you the address where the "a" variable is stored, example 0x50302040.
But the second example (2), you are using the value that address (0x50302040) points to, which returns 15000 which equals to 0x3a98 in hexadecimal.
what happened when an int is cast to a char*
If int has a value of 15000, now char* points to the address 15000, which is clearly wrong.
why the error (3) has occurred while 'printf("b:%p\n",b)' is working.
Because your pointer is a char* pointer, therefore the character sequence overload (ostream& operator<< (ostream& os, const char* s); is used, and since your pointer doesn't point to a character sequence (in fact, it doesn't point to anything since you assigned an invalid value to it), your program crashes.
Theres a ostream& operator<< (void* val); overload that will just print the address of the pointer, but you need to explicitly cast your char* pointer to a void* pointer to use it:
std::cout << "b:" << (void*)b << std::endl; // Prints 0x3a98 (15000)
If we declare:
int i;
int *ptr1 = &i;
*ptr1=10;
cout << ptr1;
Here ptr1 will give the address.
But:
char *ptr2;
ptr2="Priyesh";
cout << ptr2;
Here it will give the content of the character pointer.
Why is there such a difference?
operator << is overloaded specially for char pointers - the assumption is that if you try to print a char pointer, you actually want to print the string it points to.
If you want to print it the same way as any other pointer, cast it to void* first:
char *ptr2;
ptr2="Priyesh";
cout << static_cast<void*>(ptr2);
(or cout << (void*)ptr2;)
Because there's an operator<< overload that specifically takes a const char* argument to print it as a string.
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
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
void f(char **x)
{
(*x)++;
**x = 'a';
}
int main()
{
char str[]="hello";
f(&str);
cout << str << endl;
return 0;
}
Please tell me why this program is giving compilation Error.I am using the g++ compiler
Error :temp1.cpp:16:8: error: cannot convert ‘char (*)[6]’ to ‘char**’ for
argument ‘1’ to ‘void f(char**)’
Arrays can be implicitly converted to pointers, but that doesn't mean that the implicit "pointer equivalent" already exists.
You are hoping that f(&str); will implicitly create both a pointer to str and a pointer to that pointer.
This small (working) change illustrates this point:
int main()
{
char str[]="hello";
char *pstr = str; // Now the pointer extists...
f(&pstr); // ...and can have an address
cout << str << endl;
return 0;
}
You are passing pointer of constant char to the function but in function you are taking it as pointer of pointers. That is the problem. I commented out below where the problem lies.
[Off topic but N. B. : Arrays and pointers are different concept.]
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
void f(char **x) //**x is pointer of pointer
{
(*x)++;
**x = 'a';
}
int main()
{
char str[]="hello";
f(&str); //You are passing pointer of constant char.
cout << str << endl;
return 0;
}
You're going to run into a serious problem with your function f since &str and &str[0] both evaluate to the same value ... as other posters have pointed out, these operations point to different types, but the actual pointer r-value will be the same. Thus in f when you attempt to double-dereference the char** pointer x, you're going to get a segfault even if you attempted something like a cast to massage the type differences and allow compilation to happen with errors. This is because you are never getting a pointer-to-pointer ... the fact that &str and &str[0] evaluate to the same pointer value means that a double-dereference acually attempts to use the char value in str[0] as a pointer value, which won't work.
Your problem is that you're treating arrays as pointers, when they're not. Arrays decay into pointers, and in this case, it doesn't. What you're passing in is a char (*)[6] when it expects a char **. Those are obviously not the same.
Change your parameter to char (*x)[6] (or use a template with a size parameter):
template <std::size_t N>
void f(char (*x)[N])
Once inside, you try to increment what x is pointing to. You can't increment an array, so use an actual pointer instead:
char *p = *x;
p++;
*p = 'a';
All put together, (sample)
template <std::size_t N>
void f(char(*x)[N])
{
if (N < 2) //so we don't run out of bounds
return;
char *p = *x;
p++;
*p = 'a';
}
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.