Passing References to Pointers in C++

Passing pointer by reference in C

In C, pass by reference is emulated by passing a pointer to the desired type. That means if you have an int * that you want to pass to a function that can be modified (i.e. a change to the int * is visible in the caller), then the function should accept an int **.

In your specific case however, this isn't what you want. You only need to pass an int * to your function which it can then dereference implicitly via the [] operator and change the elements of the array.

void sort(int *arr, int s, int e)
{
int temp = 0, i, j;
for (i=0;i<e;i++)
{
for (j=i+1;j<e;j++)
{
if (arr[i]>arr[j])
{
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}

why can't we pass the pointer by reference in C?

From The C Programming Language - Second Edition (K&R 2):

5.2 Pointers and Function Arguments

Since C passes arguments to functions by value, there is no direct way
for the called function to alter a variable in the calling function.

...

Pointer arguments enable a function to access and change objects in
the function that called it.

If you understand that:

void fn1(int x) {
x = 5; /* a in main is not affected */
}
void fn2(int *x) {
*x = 5; /* a in main is affected */
}
int main(void) {
int a;

fn1(a);
fn2(&a);
return 0;
}

for the same reason:

void fn1(element *x) {
x = malloc(sizeof(element)); /* a in main is not affected */
}
void fn2(element **x) {
*x = malloc(sizeof(element)); /* a in main is affected */
}
int main(void) {
element *a;

fn1(a);
fn2(&a);
return 0;
}

As you can see, there is no difference between an int and a pointer to element, in the first example you need to pass a pointer to int, in the second one you need to pass a pointer to pointer to element.

Passing by reference in C

Because you're passing the value of the pointer to the method and then dereferencing it to get the integer that is pointed to.

Can I take a reference of a pointer in C++?

I am not sure what your problem is, as the error code given does not match your code.

Your second example with int Foo(const Obj* &ptr) works exactly as intended, and compiles fine if you make DoSomethingconst.

To comment your three thoughts:

  1. If you const things correctly, the error goes away.
  2. I really, really dislike such out-paramteres. It is much cleaner to return a struct or a pair of int and pointer. That way the caller can write const auto[ret, p] = Foo(); and not have to explicitely declare the pointer that you may not want to use.
  3. Passing pointers to pointers is C-style, due to lack of references, and just make the code harder to read, with no benefit.

Below is slightly modified code that compiles fine, with a better Foo too, as mentioned in my answer to 2.:

#include <utility>

struct Obj
{
void DoSomething() const;
};

// This is ugly of course, used just to have a valid ptr to return
Obj global;

int Foo(const Obj* &ptr) {
// do something...
ptr = &global;
return 5;
}

std::pair<int, const Obj*> BetterFoo()
{
// do something...
return {5, &global};
}

int main() {

const Obj* p1 = nullptr;
int ret1 = Foo(p1);

const auto[ret2, p2] = BetterFoo();

p1->DoSomething();
p2->DoSomething();
}

Is passing pointer by value or by reference the same

What is the difference between passing a pointer by reference and passing a pointer by value in C?

There is no such thing as passing a pointer by reference in C, all variables are passed by value, even pointers.

My understanding is when you pass arguments to methods a new stack frame is created and those values are copied to different memory addresses unless passed by reference. If passed by reference the memory addresses are passed.

Again, the pointers are not passed by reference, a copy of the value stored in the pointer is passed, i.e. the address where it points to, you can test this by changing the value of the pointer inside the function, and check how that reflects on the original pointer, spoiler, it doesn't.

When working with pointers I noticed that if I pass a char by value and modify it in a different stack frame when I return back to the main stack frame the value of the ptr has been modified.*

What you are passing is an address, a memory location where some data is stored, when you change the data stored in that memory address it will be permanent, no matter where you do it, in fact that is one of the advantages of using pointers, for you to change the contents of some variable outside the scope where it's declared.

Pass by reference and pointers

There is no pass by reference in C, it's always pass by value.

C developers can emulate pass by reference, by passing the pointers to a variable and the accessing it using dereferencing within the function. Something like the following, which sets a variable to 42:

static void changeTo42 (int *pXyzzy) {
*pXyzzy = 42;
}
:
int x = 0;
changeTo42 (&x);

Contrast that with the C++ true pass by reference, where you don't have to muck about with pointers (and especially pointers to pointers, where even seasoned coders may still occasionally curse and gnash their teeth):

static void changeTo42 (int &xyzzy) {
xyzzy = 42;
}
:
int x = 0;
changeTo42 (x);

I would implore ISO to consider adding true references to the next C standard. Not necessarily the full capability found in C++, just something that would fix all the problems people have when calling functions.

C - pass by reference?

pass them as pointers. If you do not return the value - declare functions void, or return something

void doStuff(int *v)
{
*v = *v + 10; // main->value = 10
}

void otherStuff(int *v)
{
*v = *v - 10; // main->value = 0
}

and in the main

        doStuff(&value); // "value" = 10
/*....*/
otherStuff(&value); // "value" = 0

int *v in the function means that v is the pointer to the int object.
in the function call &value passes the pointer (address) to the value.
Dereferencing the pointer v in the function - all poerations are actuqally done on the value.



Related Topics



Leave a reply



Submit