Home > Mobile >  Data in int* argument of function not returned caller
Data in int* argument of function not returned caller

Time:05-18

Compiled with g on WSL2, sample output of

#include <stdlib.h>
#include <stdio.h>
#include <vector>
using std::vector;

vector <int> powers_2(const int npow) {
    vector <int> v;
    int j = 2;
    for (int i=0; i<npow; i  ) {
        v.push_back(j);
        j*= 2;
    }
    return v;
}

void pow_2(const int npow, int *v, int *nv) {
    vector <int> w = powers_2(npow);
    *nv = w.size();
    v = (int*)malloc(*nv * sizeof(int));
    for (int i=0; i<*nv; i  ) {
        v[i] = w[i];
        printf("%d %d %d\n",i,v[i],w[i]);
    }
}

int main() {
    int *y;
    int ny;
    pow_2(3,y,&ny);
    printf("\n in main\n");
    for (int i=0; i<ny; i  ) {
      printf("%d %d\n",i,y[i]);
    }
}

is

0 2 2
1 4 4
2 8 8

 in main
0 1
1 0
2 1091723517

So the argument int* v is set in pow_2, but the data is not returned to caller. Why?

CodePudding user response:

There is a difference between passing function arguments by value, by pointer and by reference.

The line

pow_2(3,y,&ny);

will pass the value of y to the function pow_2, which means that a copy of the value of the variable y will be made, which will exist as the local variable v in the function pow_2. This is not what you want, because changing the variable v in the function pow_2 will only change that variable, but it won't change the value of the original variable y in the function main.

What you instead want is to pass the variable y itself to the function pow_2, not its value, so that it can be changed by the function pow_2. There are two ways of doing this. You can pass the variable y

  • as a reference, or
  • as a pointer

to the function pow_2.

To make the function pow_2 take a reference to an int * instead of the value of an int *, you can change the line

void pow_2(const int npow, int *v, int *nv) {

to

void pow_2(const int npow, int * &v, int *nv) {

Alternatively, you can make the function pow_2 take a pointer to an int * instead of the value of an int *. You can change the line

void pow_2(const int npow, int *v, int *nv) {

to

void pow_2(const int npow, int **v, int *nv) {

However, this will require you to rewrite the function pow_2 so that the pointer is deferenced whenever it is used:

void pow_2(const int npow, int **v, int *nv) {
    vector <int> w = powers_2(npow);
    *nv = w.size();
    *v = (int*)malloc(*nv * sizeof(int));
    for (int i=0; i<*nv; i  ) {
        (*v)[i] = w[i];
        printf("%d %d %d\n",i,(*v)[i],w[i]);
    }
}

Also, you will have to call the function differently. You will have to change the line

pow_2(3,y,&ny);

to:

pow_2(3,&y,&ny);

Therefore, passing the variable as a reference is easier than passing it as a pointer.

  •  Tags:  
  • c
  • Related