Char pointers vs Int pointers passed to functions - c++

I thought I understood pointers, but I think there's a nuance by how they're treated differently that I'm not quite following. When I pass an integer pointer or the address of an integer to showInt, it will print out the same memory address as it would outside the function. However. When I pass the following pointer to showChar;
char* value = "One";
showChar(value);
The address of the first element is different inside the function than it is outside the function. I understand that this is behaviour consistent with passing by value, and that a copy of the pointer is made within the function, however I was under the impression that a copy of a pointer still held the same address. Why is it different when dealing with pointers to char? If the char pointer just stores the address of the first element of the string literal, then why would the pointer in the function not point to the same memory location, but instead point to a new area in memory? That suggests to me that it isn't copying a char pointer, but creating a new char pointer and assigning it the value pointed to by the original pointer. If so, I don't understand why.
I understand that you can access the pointer address in the function by passing a pointer-to-pointer, or a reference-to-pointer instead, but why this is the case still confuses me.
Passing a pointer to char;
void showChar(char* name){
cout << name << endl;
cout << &name << endl;
}
Passing a pointer to int;
void showInt(int* num){
cout << num << endl;
cout << *num << endl;
}

The first line in showChar:
cout << name << endl;
will print the contents behind the pointer name, since the IO streams operators in C++ are overloaded to print char-pointers as text instead of the pointer as a number.
With the second line in this function
cout << &name << endl;
you don't print the pointer address name but instead the pointer (address) of the local variable name (which happens to be of a pointer type). That's taking the reference one time too much. What you want is change the behavior of how operator<<(ostream &, char*) works, namely printing the pointer address instead of printing a C-string.
You can do this by simply converting the pointer before passing it to cout, like this:
void showChar(char* name){
cout << (void*)name << endl;
}

Your showChar and showInt functions are printing different things.
In showChar, this:
cout << &name << endl;
prints the address of name, which is a local variable. In showInt, you don't print the value of &num; rather you print the value of num, which is an address, but not the address of a local variable.
In showChar, if you want to print value of name as an address, you'll need to convert it to some other pointer type such as void*:
cout << (void*)name << endl;
because the overload of operator<< for char* dereferences the char* pointer and prints the C-style string that it points to.
In more detail:
void showChar(char* name){
cout << name << endl; // prints the contents of the string that
// `name` points to
cout << &name << endl; // prints the address of the local variable `name`
}
void showInt(int* num){
cout << num << endl; // prints the value of the pointer `num`
cout << *num << endl; // prints the value of the `int` object that
// `num` points to
}

Related

Address of an array different with the address of the first element?

As I know address of array a is the address of first element of this array.
void func(int a[])
{
cout << "address in func: " << &a << endl;;
cout << "GT: " << &a[0] << endl;
}
int main ()
{
int a[] = {0,1,2,3};
cout << "address in main: " << &a << endl;
cout << "address in main a[0]: " << &a[0] << endl;
func(a);
}
Output:
address in main: 0x7ffef67d6790
address in main a[0]: 0x7ffef67d6790
address in func: 0x7ffef67d6778
GT: 0x7ffef67d6790
Why address of array a in func() difference with address of a[0]?
Why address of array a in func() difference with address of a[0]?
Because you're calling the function func() passing a by value. This means the a inside the function func() is actually a copy of the original decayed pointer that you're passing to func() from main(). And since they're different variables, they have different addresses. Thus by writing cout << &a; you're printing the address of this separate local variable named a.
If you want to print the original address, you should write inside func():
void func(int a[])
{
//---------------------------------v---------->removed the &
cout << "address in func: " << a << endl;;
cout << "GT: " << &a[0] << endl;
}
Demo
address in main: 0x7ffcfb0a4320
address in main a[0]: 0x7ffcfb0a4320
address in func: 0x7ffcfb0a4320
GT: 0x7ffcfb0a4320
As it has been explained in the comments, you're not passing the "same" variable to your function.
When you're calling your function, it makes a local copy within it of your array of int.
In order not to waste memory, and let's say you upgrade your program and now, you're not passing to your function an array of int but a std::vector which is quite big, we have in C++ arguments passed by references (myType & myVar).
This is the same than passing an argument by pointers in C.
Passing something by reference actually creates an ALIAS to the variable passed. So you'd now have 2 ways to act on the variable : the variable itself in your main program, and the alias in your function.
Obviously, if you do not want to modify it in the function, you can pass it by const reference (const myType & myVar) which is the same than in C with const *.
It is a fallacy inherited from C that
void func(int a[])
would pass an array to the function.
While int a[] looks like an array you can't actually pass an array to a function. An array always decays to a pointer and the pointer is actually what you pass to the function. So the above is equivalent to writing
void func(int *a)
and maybe now you can see why &a, the address of the local pointer, and &a[0] the address of the first element of the array are different.

Pointers and addresses in C++

I am messing around a little with pointers. Please take a look at the following results (addresses).
1st code:
#include <iostream>
int main(){
int a = 5;
void* pointer = &a;
std::cout << a << std::endl << &a << std::endl;
std::cout << pointer << std::endl ;
std::cin.get();
}
Result:
2nd code:
#include <iostream>
int main(){
int a = 5;
void* pointer = &a;
std::cout << a << std::endl << &a << std::endl;
std::cout << &pointer << std::endl ;
std::cin.get();
}
Result:
Why does the address of the variable a change between the two codes?
In the first case, you never take the address of pointer, so pointer can be stored in a register, or even not at all. (Modern compilers are very clever, and modern machines have many registers.)
For instance, gcc 11 keeps the value in a register without optimization, and with -O2 it just inserts the address of a directly. (Assembly here, for the curious.)
In the second case, you do take the address of pointer, so it must be stored somewhere in memory.
This means that a might be stored in a different place in order to make room for it.
Also, some platforms randomize storage locations in order to make programs less hackable, so it's usually not a good idea to assume that things will have the same address in different "runs".
In the first code poiner stores the address of variable a, and by command.
std::cout<<pointer<<std::endl;
You print the address of a. That's it.
In the second code pointer also stores the address of variable a, but &pointer is the address of variable pointer. Try the following
#include <iostream>
int main(){
int a = 5;
void* pointer = &a;
void** pointer_to_pointer = &pointer;
std::cout << a << std::endl << &a << std::endl << pointer << std::endl;
std::cout << &pointer << std::endl << pointer_to_pointer;
std::cin.get();
}
The output for me is
5
0x7aba1bd92e94
0x7aba1bd92e94
0x7aba1bd92e98
0x7aba1bd92e98
It is very simple.
int a and void* pointer are two distinct variables or I better say memory locations on the stack. a holds a value like 5 in its location. pointer holds the address to a's memory location. pointer itself is stored in a different location and when you write std::cout << &pointer << std::endl; it will print the address of the pointer variable, not the contents of it which is a's address.
As a simplified example:
Consider 0x4 as the address of pointer itself and the value inside it is 0xC. This value points to a's location. In order to read the value of a(which is 5), you first have to go to 0x4 to read its content. Its content is 0xC and now you have successfully found out that a's location is 0xC. Then you have to go to 0xC and at that address, you will find the value 5.
You look at -> 0x4( content == 0xC ) -> 0xC( content == 5 ) -> done!

Confusing about char* in c++

test code:
#include <iostream>
using namespace std;
int main()
{
const char* b="str";
cout << b << endl;
cout << *b << endl;
cout << &b << endl;
cout << *(&b) << endl;
return 0;
}
result:
str
s
0x7ffdf39c27f0
str
I run my code on the web runoob online compiler
Why I get these results? I looked some questions about char*, but not enough for me to understand. Can someone explain that to me? Pictures are best.
I want to know more about it with books or blogs recommended.
By the way, usingchar b[] instead of const char*, I get the same results.
Thanks a lot for all of you.
I just want to know why a char pointer's value is not an address.
I think adress is like 0x7ffdf39c27f0. an memory adress.
But const char* b = "str". b is just str.
And I found that *b is the same as *("str").
So I want to know what happened in the memory? why a char pointer's value is not an address?
To understand what the code outputs, you need to understand that C++ output streams (objects with a type such as std::ostream) and therefore objects (such as std::cout) have a number of overloads of operator<<(). The overload that is called depends on the type of argument provided.
I'll explain your second example, but the explanation for the first example is almost identical.
const char* b="st\0r";
cout << b << endl;
cout << *b << endl;
cout << &b << endl;
cout << *(&b) << endl;
cout << b expands to cout.operator<<(b) where b has type const char *. That overload of the operator function ASSUMES the argument points to (the first character of) a nul terminated string, which is represented in memory as an array of char that ends with a char with value '\0' (zero). The operator function outputs each character it finds until it reaches a '\0' character. The first '\0' found is the one YOU explicitly inserted after the 't', so the output st is produced. The fact that your string has a second '\0' after the 'r' is irrelevant, since the operator function stops at the first one it finds.
cout << *b expands to a call of a different overload of operator<<() that accepts a single char, and outputs that char. *b is the value of the first character in the string represented by b. So the output s is produced.
In cout << &b, &b has type const char ** or (equivalently) char const **. There is no overload of an output stream's operator<<() that accepts a const char **, but there is an overload that accepts a const void *. Since any pointer (other than pointer-to-member or pointers to functions) can be implicitly converted to void *, that conversion is performed (by the compiler), so the overload matches, and is called. That particular overload of the operator<<() prints the address in memory.
The implicit conversion in the third case doesn't happen in the first two cases, since a call that doesn't require an implicit conversion is a better match than a call which does.
In the last statement *(&b) is equivalent to b. This is the case because & is the address-of operator in this code, and the * is the dereference operator (which is the inverse of the address-of operator). So the last statement produces the same output as cout << b.
cout << b << endl;
You are printing the string b
cout << *b << endl;
You are printing the pointer that points to the first character of b., so is the same as:
cout << b[0] << endl;
cout << &b << endl;
&b is the memory address of b, which means the address memory to store b in the computer.
cout << &b << endl;
So, you're printing the memory address of b here. The computer store b in the memory address 0x7ffdf39c27f0, so that's what you get.
cout << *(&b) << endl;
You are printing a pointer that points to the memory of b, so you print the value at the memory address of variable b which is the same as
cout << b << endl;
edit: A pointer contains an address that (usually, it could point at a function, for example) represents the location of an object, and to print a pointer (usually) prints the value of that memory address. Because char * is intimately linked with null-terminated strings, there is a special overload for pointers to characters to print the pointed-at string.
A pointer variable is still a variable and will have an address of its own, so &b results in a pointer to a pointer, a char ** in this case and because it is no longer a char *, cout << &b; prints the address of b, not the address pointed at by b or the string pointed at by b.

C++ - Null Pointers [duplicate]

This question already has answers here:
Why does std::cout output disappear completely after NULL is sent to it
(3 answers)
Closed 8 years ago.
I'm learning about pointers in C++. I wrote this simple program to show what I had a problem with:
#include <iostream>
using namespace std;
int main() {
cout << "test1";
char *ptr = 0;
cout << ptr;
cout << "test2";
}
When I run the program, it doesn't output "test2" at the end, instead only "test1". This should mean that it crashed when I tried to print out the value of ptr? I tried stepping through it in Eclipse debugger and it looks like every line gets executed but doesn't it throw an error or something?
char *ptr = 0;
cout << ptr;
There's an overload of the << operator that takes a char* operand, which it assumes is a pointer to a C-style string.
For pointer types other than char*, the << operator would print the value of the pointer (which is an address), but treating a null char* pointer as if it pointed to a C-style string causes undefined behavior. In any case, it's not going to print the pointer value.
To print the pointer value, you can convert it to void*:
cout << "test1\n";
char *ptr = 0;
cout << static_cast<void*>(ptr) << "\n";
cout << "test2" << "\n";;
Normally you can output a pointer to cout and it will print the address contained. However, when you output a char * it is interpreted as a C-style null-terminated string. In this case, it's a null pointer and does not point to a string.
Try casting it to a void * before outputting it.

C++ pointer question

still working at C++, but this came up in my book and I don't understand what it's for:
MyClass * FunctionTwo (MyClass *testClass) {
return 0;
}
My question is what is the signifigance of the first indirection operator
(MyClass *[<- this one] FunctionTwo(MyClass *testClass))?
I tried making a function like it in codeblocks, with and without the first * and I didn't see any difference in the way it ran or it's output:
int *testFunc(int *in) {
cout << in << endl;
cout << *in << endl;
return 0;
}
int testFuncTwo(int *in) {
cout << in << endl;
cout << *in << endl;
return 0;
}
I couldn't find anywhere that explained about it in my book.
Thanks,
Karl
The MyClass * means that this function returns a pointer to a MyClass instance.
Since the code is actually returning 0 (or NULL) this means that any caller to this function gets back a NULL pointer to a MyClass object.
I think the following are better examples:
int *testFunc(int *in) {
cout << "This is the pointer to in " << in << endl;
cout << "This is the value of in " << *in << endl;
return in;
}
int testFuncTwo(int *in) {
cout << "This is the pointer to in " << in << endl;
cout << "This is the value of in " << *in << endl;
return *in;
}
void test() {
int a = 1;
cout << "a = " << a;
int output = *testFunc(&a); // pass in the address of a
cout << "testFunc(a) returned " << output;
output = testFuncTwo(&a); // pass in the address of a
cout << "testFuncTwo(a) returned " << output;
}
Apologies, but I've not done C++ in years but the syntax may be a little off.
The general format for a function that takes a single value and returns a single value in C++ is:
return_type function name ( parameter_type parameter_name )
In your case, return_type is MyClass *, which means "pointer to MyClass"
In addition, in your case, parameter_type is also MyClass *.
In other words, your code could be rewritten as:
typedef MyClass *PointerToMyClass;
PointerToMyClass FunctionTwo (PointerToMyClass testClass)
{
return 0;
}
Does that look more familiar?
Given the nature of the question, I'm going to provide a somewhat crude answer.
A pointer points to something:
int x = 123; // x is a memory location (lvalue)
int* y = &x; // y points to x
int** z = &y; // z points to y
In the above code, z points to y which points to x which stores an integral, 123.
x->y->z[123] (this is not code, it's a
text diagram)
We can make y point to another integer if we want or NULL to make it point to nothing, and we can make z point to another pointer to an integer if we want or NULL to make it point to nothing.
So why do we need pointers which point to other things? Here's an example: let's say you have a simple game engine and you want to store a list of players in the game. Perhaps at some point in the game, a player can die by having a kill function called on that player:
void kill(Player* p);
We want to pass a pointer to the player, because we want to kill the original player. Had we done this instead:
void kill(Player p);
We would not kill the original player, but a copy of him. That wouldn't do anything to the original player.
Pointers can be assigned/initialized with a NULL value (either NULL or 0) which means that the pointer will not point to anything (or cease to point to anything if it was pointing to something before).
Later you will learn about references which are similar to pointers except a pointer can change what it points to during its lifetime. A reference cannot, and avoids the need to explicitly dereference the pointer to access the pointee (what it's pointing to).
Note: I kind of skirted around your original question, but the sample code you provided has no inherent meaningful behavior. To try to understand that example without first understanding pointers in a general sense is working backwards IMHO, and you'd be better to learn this general theory first.
If you had something like int * Function() this would return a pointer to an integer. MyClass * just means that the function is going to return a pointer to an object of type MyClass. In c++ user defined objects are treated as first-class-objects, so once you create your own objects they can be passed as a parameter, returned from a subroutine, or assigned into a variable just like the standard types.
In the code blocks you posted there will be no difference in the output to the console because the thing you have changed is the type that the function returns (which is not used), the contents of the functions are identical.
When you define:
int *testFunc(int *in)
You are defining a function which returns a pointer to an int variable.
int testFuncTwo(int *in)
Returns just an int variable.
Zero in this case is undergoing an implicit cast - the first function returns (int*) 0, the second just 0. You can see this implicit cast in action if you change the prototype of your example function from returning a MyClass* to just returning a MyClass - if there's no operator int method in MyClass, you'll get a nice error.