Difference in passing by pointer -C++ - c++

What is the difference in the following code:-
int a;
int *p;
p=&a;
function(p);
and
int a;
function(&a);
I was reading a book where sometimes they have used the first code and sometimes the other. Its not a good book though (by a local author).
Will both codes work the same way or is there any difference?
Also is there any difference in terms of efficiency and does it matter that much?
Thanks

For a reference, the object must be already existing in order to reference it. As for a pointer, the object does not need to be already existing when declaring a pointer
Example:
int &i = 10; //Invalid
const int &i = 10; //Valid
also
you cannot declare an array of references:
int &tab[] = {2,3}; //Invalid
int * tab[] = {2,3}; //Valid
In practice, reference are mostly used as functions parameters and return values;

As far as I know compiler implements references as pointers. So there should be no difference in performance. But references are more strict and can protect you from making mistakes. For example you can't rebind references or can't perform arithmetic with them
Also some people prefere to pass pointers to the function that modify object. For example
void changeVal(int *p)
{
*p = 10;
}
They say it's more readable when you see:
changeVal(&var)
than
changeVal(var);
EDIT
You can think of reference as another name of the object it refers to. So all the changes made to reference are applied to the object. Here is an example:
void foo_copy(int a) //pass by copy
{
a = 10; //changes copy
}
void foo(int &a) //bass by reference
{
a = 10; //changes passed value
}
void foo(int *a) //pass an adress of a
{
(*a) = 10; //change a value pointed by a
a = nullptr; //change a (the pointer). value is not affected
}

In above two approaches, Both are using pointers, there is no difference except memory equal to sizeof(int *) will be allocated on stack for "int *p".
In case of call by reference, Refer. It seems you are beginner and learning things, you will come to know more about passing by reference and its use more while using copy constructor in classes.

The two code snippets should be equivalent when compiled with a modern compiler. The extra declaration and assignment (p=&a;) is optimised away.

Related

Reference member variable memory size optimization [duplicate]

I have been told that references, when they are data members of classes, they occupy memory since they will be transformed into constant pointers by the compiler. Why is that? Like why does the compiler(I know that it is implementation-specific in general) make a reference a pointer when they are part of a class, as opposed to when they are a temporary variable?
So in this code:
class A{
public:
A(int &refval):m_ref(refval){};
private:
int &m_ref;
}
m_ref will be treated as a constant pointer(i.e. they do occupy memory).
However, in this code:
void func(int &a){
int &a_ref = a;
}
the compiler just replaces the reference with the actual variable(i.e. they do not occupy memory).
So to simplify a little, my question basically is: What makes it more meaningful to make references into constant pointers when they are data members than when they are temporary variables?
The C++ standard only defines the semantics of a reference, not how they are actually implemented. So all answers to this question are compiler-specific. A (silly, but compliant) compiler might choose to store all references on the hard-disk. It's just that it proved to be the most convenient/efficient to store a reference as a constant pointer for class members, and replace the occurence of the reference with the actual thing where possible.
As an example for a situation where it is impossible for the compiler to decide at compile time to which object a reference is bound, consider this:
#include <iostream>
bool func() {
int i;
std::cin >> i;
return i > 5;
}
int main() {
int a = 3, b = 4;
int& r = func() ? a : b;
std::cout << r;
}
So in general a program has to store some information about references at runtime, and sometimes, for special cases, it can prove at compile time what a reference is bound to.
The reference (or pointer) has to be stored in memory somewhere, so why not store it along with the rest of the class?
Even with your example, the parameter a (int &a) is stored in memory (probably on the stack), then a_ref doesn't use any more memory, it's just an alias, but there is memory used by a.
Imagine that a class is just a user defined data type. You need to have something which can lead you to the actual thing that you are referencing.
Using the actual value in the second case is more about the compiler and his work to optimize your code.
A reference should be an alias to some variable and why should this alias use memory when it could be optimized to be taken directly from the stack.

Reference vs. pointer

What is the difference? Because this:
int Value = 50;
int *pValue = &Value;
*pValue = 88;
and ref version do the same:
int Value = 50;
int &rValue = Value;
rValue = 88;
Which one is better to use? Thanks.
In this case, they are equivalent.
It does not matter which you use, and neither is "best".
If you really want to choose between them then the reference is probably more idiomatic. I generally stick to references wherever I can because my OCD likes it: they feel "tighter", cannot be re-bound (with or without you noticing) and don't require a dereference to get to the value.
But I'm not aware of any general consensus on the issue for cases such as this.
Also note that the two may not compile to the same code if your implementation does not implement references with pointers, though I know of no implementation like that, and you wouldn't notice the difference anyway.
A pointer is the address of the memory location. You can change the value of that address to point at different memory addresses.
A reference is an alias of the variable. You can only assign this alias during declaration. You cannot change which variable the reference is an alias of after it's declared.
The following pointer assignments are not possible with references.
int a = 10;
int b = 20;
int* pInt = NULL; // A pointer pointing at nothing.
pInt = &a; // pInt now points at a
pInt = &b; // pInt now points at b
As for which one is better, it all depends on context.
I use references for method and function parameters.
void updateFoo(Foo& foo)
I use references to alias complex objects.
Foo& foo = bar.getBaz().getFoo(); // easy access to foo
I use pointers for dynamically allocated objects.
Foo* pFoo = new Foo();
I use pointers for things which may point at different values (including no value at all).
Foo* pFoo = NULL;
if (condition1)
pFoo = &foo1;
else (condition2)
pFoo = &foo2;
As a general rule, I default to references and use pointers in places where the limitations on references cause problems.
The differences are:
Reference is an alias of an object and has the same address as the object.
int a; // address of a : 0x0012AB
int &ref = a; // address of ref : 0x0012AB (the same)
References must be initialized :
int &ref = a; // GOOD, is compiling
int &ref; // BAd, is not compiling
Pointer is another variable that holds an address:
int a = 5; // address of a : 0x0012AB
int *p = &a; // address of p : 0x0012AF (is different )
// value of a is 5
// value of p is 0x0012AB (address of a)
Pointers can be NULL
int *p = NULL;
My rule of thumb is to favor using a reference or const reference, unless a pointer is required.
The reference may not be reseated, and it is syntactically cleaner. The reference also guarantees to you that the reference is not NULL.
I may also use a pointer for convenience when using arrays.
I agree with justin's answer and would like to clarify it with the tiniest example.
Suppose you don't quite remember the syntax of a 2D image geometric library: is it
bool BooleanOr( const Bitmap & input1, const Bitmap & input2, Bitmap * output );
or is it
bool BooleanOr( Bitmap * output, const Bitmap & input1, const Bitmap & input2 );
If in your company everybody uses pointers for outputs and const references for inputs it's virtually impossible to make a mistake: when you see calls such as
BooleanOr( thisBitmap, thatBitmap, & anotherBitmap );
you immediately know the syntax.
Great answers here. I would like to point out 2 specific usages of references:-
Case 1: While implementing operator[]. This operator typically needs to return something that can be used as the target of an assignment Example:-
vector<int> v(20);
v[1] = 5; //The target of the assignment is the return value of operator []
Here the operator [] returns a reference of the element at the specified index in the vector. Had operator [] been designed to return a pointer to the element at the specified index the 2nd line would have to be written like this:-
*v[1] = 5
Now that makes v look like it's a vector of pointers - which it's definitely not!! Thus for sanity to prevail - the operator [] returns a reference and not a pointer to the indexed element in the vector
Case 2: No explicit null check required for references. Some answers have already talked about it - wanted to present the advantage using a code snippet:-
void fun(const int& val)
{
cout << val;
}
void fun(const int* val)
{
if (val){ //Additional overhead with pointers
cout << *val;
}
}

Is there a case where element selection by reference and element selection through pointer operation are both valid?

My background is in more managed languages (C#, python) but I am becoming more experienced in C/C++. I am familiar with why the selection by reference (.) and selection through pointer operation (->) operators are different. In all cases I have encountered, if you use the incorrect one, it will result in a compile error. If that is the case, they why were they not made into one operator? Is there a case where using either on the same object results in different, meaningful and useful results?
This question inspired by this answer:
Is this right way to call a function in c++?
In C++ you can overload the ->-operator, which is used in pretty much all smart pointer implementations. However, some of those also have their own methods, i.e. to release a reference.
struct test {
int x;
};
std::shared_ptr<int> ptr(new test);
// Write to member x of the allocated object
ptr->x = 3;
// Reset the shared pointer to point to a different object.
// If there are no further shared_ptrs pointing to the previously allocated one,
// it is deleted.
ptr.reset(new test)
Additionally, it would be quite messy for the compiler to resolve operator-. for something like multiple-level pointers, i.e. test*** ptr. With your logic, ptr.x, (*ptr).x, (**ptr).x and (***ptr).x would all be the same.
You cannot apply -> to a reference to a basic type and you cannot apply . to a pointer, but you can apply both to a user-defined type and they will have different meanings. The simplest example is a smart pointer, like std::shared_ptr:
struct A { int x; };
std::shared_ptr<A> p(new A);
p->x = 10;
p.reset();
Is there a case where element selection by reference and element selection through pointer operation are both valid?
Since you can overload operator->() in C++, you can actually arrive at situations where you can use -> and . interchangeably on the same object. You can even engineer things so that you get a different result, as per this example:
#include <iostream>
struct Bar
{
void hello() const { std::cout << "Bar!!!\n"; }
};
struct FooBar
{
Bar bar;
void hello() const { std::cout << "FooBar!!!\n"; }
const Bar* operator->() const {return &bar; }
};
int main()
{
FooBar fb;
fb->hello();
fb.hello();
}
Of course, in real code you would never do something as crazy as this (although I have seen this kind of thing in "production" code).
the short answer would be a smart pointer
you can access the smart pointer class arguments using the "." (if you make your own smart pointer class you can extract from there for instance the current reference count) while you would use the "->" operator to access whatever is being stored using the smart pointer.

How to pass parameters for output in C++ [duplicate]

This question already has answers here:
What are the differences between a pointer variable and a reference variable?
(44 answers)
Closed 9 years ago.
Some of methods that I see in C++ code are of this structure:
void Class::method1(int &a);
and are called like this:
int a;
class->method1(a);
But sometimes I see structures like:
void Class2::method2(int* a);
And these methods are called like this:
int a;
class2->method2(&a);
I understand that in the first case the method accepts an address of a variable, and in the second - pointer to a variable, right?
Could someone explain to me what is the difference between these two approaches, and when to use which?
Also, in the first example, it seems that a method can be taking "int& a" or "int a", and in both cases we would call it the same way: int a; class->method1(a); ? This seems confusing.
Thanks.
void Class::method1(int &a);
This is passing by reference.
void Class2::method2(int* a);
This is passing the pointer. In class2->method2(&a);, & is the address of operater.
First one is called using a reference to a variable, second one - using a pointer. There are some difference between the two concepts. I encourage you to google this, but the most important ones I can think of right now are that a reference can not be constructed without pointing to an existing object and that a pointer can be NULL.
void Class::method1(int &a) means you are passing a by reference and the caller can expect a to be modified.
void Class2::method2(int* a) means you are passing a by pointer and the caller can expect the thing to which a points to be modified.
Personally I don't like pass by reference since the caller doesn't quickly know if a will be modified as the calling syntax for pass by reference and pass by value are identical. Passing by constant reference void Class::method1(const int &a) is better still since then a cannot be modified and you can gain an efficiency in not taking value copies if a is a large object.
However many folk differ in their opinion and say that you should pass by pointer if the function allows the pointer to be null; i.e. can your function do something useful without a inputted?
In the first case, the method accept a reference to the variable.
It means that if a is modified inside the method1, it will be modified after the function returns.
In the second case, it accepts a pointer to the variable. A pointer is the memory adress of the variable. It's what the & retrieves : The address (aka a pointer to a).
Both type have essentially the same purpose : Being able to modify a variable of a different scope.
See that example :
void fooPointer (int* pointer) {
*pointer += 1;
}
void fooReference (int& reference) {
reference += 1;
}
int main () {
int a = 0;
std::cout << a; // Ouputs 0
fooPointer (&a);
std::cout << a; // Outputs 1
fooReference (a);
std::cout << a; // Outputs 2
}
As you can see, both allow you to do the same here. But using references is usually easier and more readable, because everything is done implicitly, so you don't have to reference (*) or dereference (&) your variables.

C++ Parameter Reference

void (int a[]) {
a[5] = 3; // this is wrong?
}
Can I do this so that the array that is passed in is modified?
Sorry for deleting, a bit new here...
I have another question which might answer my question:
If I have
void Test(int a) {
}
void Best(int &a) {
}
are these two statements equivalent?
Test(a);
Best(&a);
void Test(int a[])
{
a[5] = 3;
}
just alternate syntax for:
void Test(int* a)
{
*(a+5) = 3;
}
No array is passed, just a pointer. The original array is modified.
As for your second revision, given:
void Test(int a)
{
}
void Best(int &a)
{
}
then
Test(aa); // Passes aa by value. Changes to a in Test() do not effect aa
Best(aa); // Passes aa by reference; Changes to a DO effect aa
Best(&aa); // Is a syntax error: Passing a pointer instead of an int.
If you get the variable not by reference and not by pointer, it means that the function is essentially isolated, getting an ad-hoc copy of a. No matter what you do (without trying to hack the stack or things like that) you wouldn't have access to that value in the calling context.
If you know something about the calling context, you may be able to do things based on some anticipation of stack contents, but it's generally a bad idea.
If your method takes a[] which is essentially a*, then yes, you can alter the contents of the cell that a points to, but you won't be able to alter a (the pointer) itself to point at something else.
Nope.
Your options for altering a value from outside the function are call by reference f(int& a), call by pointer f(int* a), and using a global (shudder...) variable.
Read the answer given here about the difference of int[] and int* in a parameter list: Difference between char* and char[] . I've really put so much love into that answer! :)
Regarding your question about your Test and Best functions, James Curran provided an excellent answer.
Your original Function should work.
If you give it a name:
#include <iostream>
// Arrays always de-generate to pointers.
void plop(int a[]) // Make sure this function has a name.
{
a[5] = 3;
}
int main()
{
int test[] = { 1,1,1,1,1,1,1,1};
plop(test);
std::cout << test[5] << std::endl;
}
This is because arrays always de-generate into pointers when passed as an argument to a function. So this should always work as expected. Assuming you don't index beyond the end of the array. Inside plop there is no way to determine the size of the array passed.
The primary motivator for passing arrays by reference is to prevent stack overflows and needless copying of large objects. For example, imagine if I had a function like this:
void foo(int x[500000000000]);
The stack would probably overflow the first time you called the function if all arrays were passed by value (but of course this is an obvious exaggeration).
This will become useful when using object-oriented methods. Suppose instead of an array, you had this:
void foo(SomeClass x);
where SomeClass is a class with 500000000000 data members. If you called a method like this, the compiler would copy x bit by bit, which would be a very long process to say the least. The same concept as you use in arrays still applies, but you have to specify that this is to be used by reference manually:
void foo(SomeClass &x);
(and don't go trying to create a 500000000000 element array to begin with unless you have a 64 bit machine and lots of RAM)