Search code examples
c++pointerspass-by-referencepass-by-valuefunction-definition

How to pass pointer to function and dynamically allocate memory within function C++


I'm trying to declare a pointer and pass that pointer to a function where memory is allocated. Here is a minimal example:

#include <string>
#include <iostream>

using namespace std;

void alloc_mem(int &size, double *x);

int main()
{

        double *X;
        int imax;

        alloc_mem(imax, X);

        cout << "imax = " << imax << endl;
        for (int i = 0; i < imax; i++) {
                cout << "X = " << X[i] << endl;
        }

        delete[]X;
        return 0;

}

void alloc_mem(int &size, double *x)
{

        size = 10;
        x = new double[size];
        for (int i = 0; i < size; i++) {
                x[i] = (double)i;
        }

}

This code compiles, but I get a segmentation fault when I try to print out the values of X. I know that I'm not passing the variable into the function correctly, but I'm not sure how to do it. I believe that I'm operating on a copy of x.

Also, this code was written to reproduce an issue I'm having in a much larger code.


Solution

  • Parameter double *xis a local variable of function alloc_mem. When the function will end its execution the variable will be destroyed. The original variable X in main knows nothing what was done with this parameter because it was passed by value that is a copy of it was used in the function.

    Either pass the pointer by pointer or by reference. For example

    void alloc_mem(int &size, double **x);
    
    void alloc_mem(int &size, double * &x);
    
    void alloc_mem(int &size, double **x) 
    {
       size = 10;
    
       *x = new double [size];
    
       for ( int i = 0; i < size; i++ ) ( *x )[i] = i;
    }
    
    void alloc_mem(int &size, double * &x) 
    {
       size = 10;
    
       x = new double [size];
    
       for ( int i = 0; i < size; i++ ) x[i] = i;
    }
    

    As for me I would define the function the following way

    double * alloc_mem( int &size ) 
    {
       size = 10;
    
       x = new double [size];
    
       for ( int i = 0; i < size; i++ ) x[i] = i;
    
       return x;
    }
    

    if size is known before calling the function then it could be written even simpler

    double * alloc_mem( int size ) 
    {
       x = new double [size];
    
       for ( int i = 0; i < size; i++ ) x[i] = i;
    
       return x;
    }
    

    Take into account that loop

       for ( int i = 0; i < size; i++ ) x[i] = i;
    

    can be substituted for standard algorithm std::iota For example

    std::iota( x, x + size, 0.0 );