2

Code

#include "stdafx.h"
#include <iostream>

void someFunc(double* pDoubleArray, int length)
{
    double* pNewDoubleArray = new double[length];

    for(int i = 0; i < length; i++)
    {
        pNewDoubleArray[i] = i * 3 + 2;
    }

    pDoubleArray = pNewDoubleArray;
}
int main()
{
    double dbls[] = { 1, 2, 3, 4, 5 };

    int length = sizeof dbls / sizeof dbls[0];

    std::cout << "Before..." << std::endl;

    for(int i = 0; i < length; i++)
    {
        std::cout << dbls[i] << ", ";
    }

    std::cout << std::endl;

    someFunc(dbls, length);

    std::cout << "After..." << std::endl;

    for(int i = 0; i < length; i++)
    {
        std::cout << dbls[i] << ", ";
    }

    std::cout << std::endl;

    while(true){ }

    return 0;
}

Output

Before...
1, 2, 3, 4, 5,
After...
1, 2, 3, 4, 5,

Here's what I am trying to do: 1. Create an array and fill it with some values 2. Pass that array as a pointer to a function that will create a new array and reassign the one that was passed in to the newly created array 3. Print out the changes

I am not seeing any changes though, and I do not know why.

4
  • 5
    Sigh. Yet again, std::vector is what you really want. Commented May 12, 2011 at 18:31
  • 1
    But not passing the vector<double> by reference will result in the same problem. Commented May 12, 2011 at 18:32
  • Can you confirm that you actually want to create a new array, rather than modifying the array you already have? Your main function seems to want the original array to be modified. Commented May 12, 2011 at 18:42
  • Yes I do want to create a new array. Commented May 12, 2011 at 18:54

4 Answers 4

1

The interface of your function someFunc is wrong. It should require the reference of a pointer's address (or the pointer to a pointer) so that you can return the address of your new array. Otherwise, you are simply modifying a local value.

void someFunc(double*& pDoubleArray, int length)
{
  double* pNewDoubleArray = new double[length];

  for(int i = 0; i < length; i++)
  {
    pNewDoubleArray[i] = i * 3 + 2;
  }

  pDoubleArray = pNewDoubleArray;
}

Your calling main function should then pass a value which can be modified:

int main()
{
  double dbls[] = { 1, 2, 3, 4, 5 };
  double* pArray = dbls;
  // ...

  someFunc(pArray, length);
  // ...

  for(int i = 0; i < length; i++)
  {
    std::cout << pArray[i] << ", ";
  }
  // ...
}
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you, this worked. Out of curiosity though - how do I pass a pointer to a pointer? I tried: void someFunc(double** pDoubleArray, int length), and then pDoubleArray = (double**)pNewDoubleArray; and someFunc((double**)pArray, length); but this resulted in my original problem of no changes occuring...
@Storm: you will need to get the address of the variable using the & operator: pArray = &dbls;. But please have in mind that changing a reference to a newly allocated instance often means that you will lose the reference to your old data. If the old data was also created on the heap (using the new keyword), it means that memory will never be reclaimed.
@Groo: I tried to do: double* pArray = &dbls; and there was an error: cannot convert from 'double (*)[5]' to 'double *'
@Storm: sorry, I didn't get what line of code you were referring to. I've updated my answer below with the example of double** as the parameter.
0

Ignoring the memory leak issue that results:

void someFunc(double* & pDoubleArray, int length)
// pass by reference ^^^ the pointer

3 Comments

The name of an array can be used as a pointer r-value, but not a pointer l-value. Your "fix" won't compile.
@Ben Voigt, are you positive about that? The accepted answer seems to say otherwise. :-)
Yes, I'm positive. The accepted answer changed the actual parameter, it isn't dbls anymore.
0

The line     pDoubleArray = pNewDoubleArray; assigns the local copy of the pointer

Either pass the pointer by reference, pass a pointer to it, or return the new value

My preference would be to return the new value, bit that's a style issue.

1 Comment

You could also just change the values in-place, thus avoiding allocating and leaking a new array, of course
0

It is unclear why you are passing the old array to a function which does not use it.

If you are changing individual values, then there is no point in creating a new array instance. If not, then simply create a new array and return it.

So, either change the original array:

void someFunc(double* pDoubleArray, int length)
{
    for(int i = 0; i < length; i++)
    {
        pDoubleArray[i] = i * 3 + 2;
    }
}

Or return the new array from the function:

// this indicates that the returned value is
// actually a new instance
double* getNewArray(double* pDoubleArray, int length)
{
    double* pNewDoubleArray = new double[length];

    for(int i = 0; i < length; i++)
    {
        pNewDoubleArray[i] = i * 3 + 2;
    }

    return pNewDoubleArray;
}

An alternative is to pass the input array by reference, but that complicates releasing unused instances.

[Edit]

To clarify this last case:

void someFunc(double** pDoubleArray, int length)
{
    double* pNewDoubleArray = new double[length];

    for(int i = 0; i < length; i++)
    {
        pNewDoubleArray[i] = i * 3 + 2;
    }

    *pDoubleArray = pNewDoubleArray;
}

void main()
{
    double dbls[] = { 1, 2, 3, 4, 5 };
    double* pArray = dbls;

    // this will change what pArray
    // points to
    someFunc(&pArray, 5);

    return 0;
}

As I've commented before, the latter approach will lead to memory leaks if pArray points to a heap allocated array before calling someFunc.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.