How does exactly this code work in C++ - c++

For example this code:
#include <iostream>
using namespace std;
void foo(int* x){ cout << "X = " << *x << endl;}
int main()
{
int value = 5;
int *p = &value;
foo(p);
foo(&value);
return 0;
}
In the first call of function foo a copy of pointer p (x) is actually created within the function and deleted as soon as the function ends, right? In the second call of foo the address of variable value is taken and a pointer x is created with that address and is deleted as soon as the function ends, right? Which of these calls is cheaper in terms of stack memory consumption? Or are both the same thing?

They're both similar. The first looks more expensive because you're creating a pointer twice, once as a local variable (inside main) and again as a function parameter (passed to foo), however the "optimization" phase of the compiler will probably turn the first into the second (assuming that the only thing you do with p is pass it, and you don't reuse it later in main).

They are almost identical. The only difference is that you have a pointer object p on the call stack in main, but if you're going to worry about that then you have issues. :)

In the first call, you are passing a variable containing the address of value.
In the second, you are passing the address of value directly.
Note that assignment operator says that both p and &value are the same, so you should be able to pass either one to the function as you have proven.

Pointers have values that can be copied like everything else. They
have value-semantics.
void foo(int* t);
takes a pointer by value. It will create a copy of the pointer
argument and use it inside its body.
int value = 23;
int *p = &value; // &value takes the address of value and use it to copy initialize p
foo(p); // copy the value of the pointer inside foo
foo(&value); // do the same but don't create a temporary

Related

Why does same pointer has different addresses

class A{};
void Foo(A *p)
{
std::cout << &p << std::endl;
std::cout << p << std::endl;
}
int main()
{
A *p = new A();
std::cout << &p << std::endl;
std::cout << p << std::endl;
Foo(p);
}
The above program prints the same value for p but different addresses for &p. Can somebody please explain why ?
The above program prints the same value for "p"
This is because one p is a copy of the other, so they both have the same value. The value of a pointer is a memory address where an object is stored so having the same value means pointing to the same object.
A function argument is a copy of the object that was passed to the function †.
but different addresses for "&p". Can somebody please explain why ?
Each p here is a separate variable and a separate object ††. Both objects exist simultaneously. The C++ standard specifies that each currently existing object has a unique address †††, so therefore each p here must have a unique address.
The Unary operator & is the addressof operator, and it returns the memory address where the operand is stored.
† Unless that function argument is a reference. In that case the reference is bound to the passed object. The p argument is not a reference.
†† Pointers themselves are objects. The memory address where a pointer stored is separate from the memory address that is its value which is the memory address of the pointed object.
††† There are exceptions in case of sub-objects, but those exceptions aren't relevant here.
void Foo(A *p)
{
std::cout << &p << std::endl;
std::cout << p << std::endl;
}
When you pass something to Foo() that something is copied into p.So the actual parameter(the something which was passed) is not the same thing as the formal parameter(p here), though they will hold the same value.
Inside Foo(), &p will print address of this formal parameter and not the address of the actual parameter that was passed.
And since the formal and actual parameter hold same value, p prints the same value.
operator & is returns Address of Variable
They are difference variable A *a and Foo(A *a) but they pointing to the same address. It's normally has difference address.
Here is a good description of stack and heap.
What and where are the stack and heap?
A short answer as others have mentioned is that:
p points to the allocated instance of A which is allocated from the heap. It is created with the operator 'new' in your code.
&p is pointing to the memory which p itself occupies.
Just as class A occupies memory (which is allocated from the heap using the 'new' operator) p occupies memory (allocated from the stack since it is a local variable).
this event occures because of copy constructors.
The copy constructor is a constructor which creates an object by initializing it with an object of the same class, which has been created previously. The copy constructor is used to −
-Initialize one object from another of the same type.
-Copy an object to pass it as an argument to a function.(this refer to your problem)
-Copy an object to return it from a function.
p is local variable that contain address of object in heap . and &p is address of p in stack. when we pass p to Foo() because of copy constructor
compiler copy p to new local variable hence we have 2 pointer that both of them refer to same location in heap memory. on of them is original p(actual parameter) and second is unnamed local variable(Formal Parameter) in Foo() method that has been built by copy constructor.
also you could see difference between p an &p in below image.

What is the issue with this static variable assignment to a pointer in local function?

int* func(int *ptr)
{
static int a = 5;
ptr = &a;
return ptr;
}
Someone asked me this question in an interview. Now the point is, the variable 'a' is static, so, unlike ordinary variables which are declared, which loses it's value (popped from stack) once the function returns, this variable retains it's value as it is a static one.
Then i didn't understand, what's the issue with this piece of code?
There is no point in having ptr as a parameter. The passed value is not used. You could change this to
int* func()
{
static int a = 5;
return &a;
}
There is no issue. a is static so it exists through the lifetime of the execution. It is syntactically invisible outside func. You are just returning the address of some "hidden" global variable.
The value (address you're pointing to) of ptr that you are passing in is NOT changing outside the function as you are changing a locally scoped copy of ptr
It needs to be passed in by reference or pointer to pointer for it to change.
int* func(int **ptr)
{
static int a = 5;
*ptr = &a;
return *ptr;
}
I'm bringing back your attention for local static variables. All time the variables will be remain same from last call. So, if you increase the variable a=a+1 then next time the value is remain 6. Here come how it happens. Each local declare new space in memory in each call. But in static variable you are telling to use same memory for every time. So, pointer will remain same. That why you are getting same address. This is not unexpected.
There isn't an issue, unless the caller doesn't understand what the function does. This is quite possible, given that people may assume the function modifies the value pointed to by the parameter.
For instance, if somebody writes code like
int foo = 0;
func(&foo);
assert(foo == 5);
They will have an issue.
The interviewer may have been looking for a solution like:
int *func(int *ptr) {
static int a = 5;
*ptr = a; //modify value being pointed to by argument
return ptr;
}
There is a thread-safety issue: returning a non-constant pointer to a makes it possible that some thread will modify the value while another thread is reading it. Data races have undefined behavior.
I'll also toss in that returning a raw pointer is horrible practice, since I haven't seen it in the other answers. int& func() should be preferred.

Passing pointer to a function in C++

I wrote the following piece of code
#include <iostream>
using namespace std;
void temp (int * x)
{
x=new int [2];
x[0]=1;
x[1]=2;
}
int main()
{
int *ptr;
temp(ptr);
cout<<ptr[0]<<endl;
cout<<ptr[1]<<endl;
return 0;
}
Running it gives seg fault, so is the memory allocation which happens inside temp function local to function? The memory gets deallocated while returning from temp? I know, that to solve this problem, I need to pass pointer to pointer ptr, but still, why exactly does this thing not work?
To alter something in a function in C, you need to pass a pointer to it. In this case, you want to alter a pointer, so you need a pointer to a pointer:
void temp (int** x)
then in the function use *x where you now have x (you will need (*x)[n], as *x[n] means something else)
Then call temp with:
temp(&ptr);
This should solve it in C, and will work in C++.
In C++, you could also pass a reference to a pointer:
void temp(int*&x)
which will allow the syntax you have already to be used unchanged.
Think about this code
void temp(int x)
{
x = 2;
}
int main()
{
int y = 3;
temp(y);
cout << y << '\n';
}
What the output going to be 2 or 3? Of course it's three. Now what's the difference between this and your example? Nothing at all. Unless you use a reference everything in C++ is passed by value. x is a copy of y, so changes to x never affect y. This is true whetever the types involved, its true of ints and its true of pointers.
C++ answer:
You are passing the int* argument into temp by value. This means that you are copying ptr into the function, and the pointer x is a completely separate object. You then assign the result of new int[2] to this copy, but the ptr in main is left unaffected. To be able to modify the pointer passed as an argument, you need to take it by reference:
void temp (int*& x)
{
// ...
}
This means that x now refers to the pointer that is passed as an argument. The alternative solution here is to return an int* instead:
int* temp()
{
int* x = new int [2];
x[0]=1;
x[1]=2;
return x;
}
int main()
{
int *ptr = temp();
// ...
}
However, the caller of temp might be unclear about the ownership of the int object. They need to delete[] it, but this isn't made explicit in the interface. Instead, you can return a std::unique_ptr.
int *ptr;
You created an automatic variable here and you passed it to
temp(ptr);
This is pass by copy so x will get the value of ptr and x scope is within the temp function. It is an automatic variable in that scope.When you return from temp its value is lost.
Now, the memory allocated and pointed to by x is in no way reflected to ptr in main. (They are not connected)
You need to do temp(int*& ptr) i.e. pass by reference. Or temp(int** ptr) i.e. pass by address
Note: You have a memory leak in your temp
You need to pass a ** because you are allocating x inside of your function.

Assigning a value to a pointer

If I have the following for example:
int *x;
x = func(a);
For the statement: x = func(a);, do we say that we are returning an address to x? Or, how exactly do we read it?
EDIT: Is it eligible to say that we are returning a pointer to x? If so, can you explain how this is done exactly? I mean, how are we returning a pointer?
x is a pointer to an int, so in other words it is the address of a memory location where an int is stored. So x = func(a) means that func returns the address of an int and stores it in the variable x.
Take care not to return the address of a local variable whose contents would be undefined after func returns.
RE: Your edit:
EDIT: Is it eligible to say that we are returning a pointer to x? If so, can you explain how is this done exactly? I mean, how are we returning a pointer?
Yes, it is certainly eligible. Try and think of and treat pointers as any other data type. Under the hood, they are just memory addresses. A pointer can be returned the same way any other data type can be returned.
Take this code for example:
int* giveMeAPointer() {
return y;
}
int* x = giveMeAPointer();
Say that "y" is declared globally as: "int* y = ...". Now the memory address being pointed to by "x" is the same as the memory address being pointed to by "y".
Now let's say that "y" was -not- declared as a pointer, but instead as a normal int (e.g. "int y = 5"). The function could do this and still be valid:
int* giveMeAPointer() {
int* result = &y;
return result;
}
*x is points to int typed variable in memory. So function func should return address to int.
int *x;
x = new int; // create your own int
*x = 5; // access - set it's value
delete x; // delete int - free memory
x = getGlobalCounter();
(*x)++; // increment global pointer
For example the getGlobalCounter function:
static int counter;
int *getGlobalCounter() {
return &counter; // return address of counter
}
But isn't always good idea to delete objects returned from functions. In that case it should result in runtime error, because of counter isn't dynamically allocated int as in top example.
If you are assigning a variable's value to the return-type of a function, then that return-type must match the variable's type. This goes the same for pointers.
So, if you have:
int* myPointer;
And...
int* func();
Then setting myPointer equal to func() will change the memory address which "myPointer" points to, to the memory address returned by func().
x is a pointer, specifically to an int. So it should be obvious that there are two memory locations used. One for the pointer and one for the memory it's pointing to (assuming the pointer is not null).
The pointer itself holds a memory address, specifically the location of the memory it's pointing to. Something like 0xa456e4fa.
Yes, func() is returning a pointer. The prototype of func would look like the following..
int * func(someObj a); //I don't know the datatype of your parameter,
//so I'm just making something up.
Notice the return type is a pointer to an int. From this and what I said previously, it should be obvious what this will return. Something of the form 0xyyyyyy, or a memory address/pointer. That memory address goes into your x pointer.
Remember that the pointer itself is not holding the data that it's pointing to, it is only the address. There's really no reason you CAN'T return a pointer. However, you do need to be careful in WHAT you return. You do not want to return the address of a local variable because that variable will go out of scope once the function has completed its execution. You'll then be returning the address of something invalid. Returning the VALUE of a local pointer however, is fine because the value you returned (the address) will be preserved as will the memory it's pointing to.
I also just realized I wrote you a book. Damn, I sure do ramble when I'm tired.
The statement just reads that x is assigned the value returned by function func. For the code to compile without errors , the func should return an address though . And for the code to execute as expected as AlexFZ pointed out , you should take care that func does not return the address of a variable local to the function.
It means that func() returns a variable of type int*.
Is it eligible to say that we are returning a pointer to x?
No, we are returning a pointer to an integer and assigning it to x since it is a pointer.
This is an example code which returns an int pointer
int* func(int a)
{
int *y = &a;
return y;
}

why does pointer get its previous value returning from a function

guys how does the ptr get its previous value? code is simple, I just wondered why it doesn't store the address value that it's been assigned within the function.
#include<stdio.h>
#include<stdlib.h>
void test(int*);
int main( )
{
int temp;
int*ptr;
temp=3;
ptr = &temp;
test(ptr);
printf("\nvalue of the pointed memory after exiting from the function:%d\n",*ptr);
printf("\nvalue of the pointer after exiting from the function:%d\n",ptr);
system("pause ");
return 0;
}
void test(int *tes){
int temp2;
temp2=710;
tes =&temp2;
printf("\nvalue of the pointed memory inside the function%d\n",*tes);
printf("\nvalue of the pointer inside the function%d\n",tes);
}
output is:
value of the pointed memory inside the function:710
value of the pointer inside the function:3405940
value of the pointed memory after exiting from the function:3
value of the pointer after exiting from the function:3406180
You passed the pointer by value.
The pointer inside test is a copy of the pointer inside main. Any changes made to the copy do not affect the original.
This is potentially confusing because, by using an int*, you're passing a handle ("reference", though actually a reference is a separate thing that exists in C++) to an int and thus avoiding copies of that int. However, the pointer itself is an object in its own right, and you're passing that around by value.
(You're also attempting to point your pointer to an int that's local to the function test. Using it will be invalid.)
The pointer is passed into the function by value, in other words a copy is made of it. In the function you change the copy, but that does not alter the value in main. If you wanted to change that, you would need to use a pointer to a pointer.
In case the other answers describing the issue are not sufficient.
The code you want so you can change the value is along these lines
test(&ptr);
void test(int **tes){
int *temp2 = new int;
*tes =&temp2;
}
Alternativly, don't mess with raw pointers. shared_ptr<> and & can be your friend!