1

In short, I'm passing an argument to a method, assigning the output of the method to a different variable, and later reference the original argument, only to find that it's value has changed!

Here I have the relevant portion of the main fragment which creates the original variable. It's logtag is QF:

Log.d("QF",""+ roiRGB[0]);
double[] lab = MathUtils.rgbTOlab(roiRGB, refRGB);
Log.d("QF",""+ roiRGB[0]);

Within MathUtils, rgbTOlab looks like this:

public static double[] rgbTOlab(double[] roi, double[] ref){
    double[] newroi = roi;
    Log.d("rgbTOlab", roi[0] + " vs " + newroi[0]);
    newroi = rgbTOxyz(newroi);
    Log.d("rgbTOlab", roi[0] + " vs " + newroi[0]);
    ...

And rgbTOxyz looks like this:

    public static double[] rgbTOxyz(double[] rgb)
{   // RGB input values must be normalized to 0..1
    Log.d("rgbTOxyz",rgb[0]+"");
    double[] newrgb = rgb;
    Log.d("rgbTOxyz",rgb[0]+ " vs " + newrgb[0]);
    // Convert RGB values to sRGB ("standard" RGB)
    for (int i=0;i<3;i++) {
        if (rgb[i] <= 0.04045) {
            rgb[i] = rgb[i] / 12.92;
        } else {
            rgb[i] = Math.pow((rgb[i] + 0.055) / 1.055, 2.4);
        }
        rgb[i] = rgb[i] * 100;
    }
    Log.d("rgbTOxyz",rgb[0]+" vs " + newrgb[0]);
    ...

And here's the logcat:

05-28 19:42:29.961 D/QF﹕ 0.16626617647060205
05-28 19:42:29.962 D/rgbTOlab﹕ 0.16626617647060205 vs 0.16626617647060205
05-28 19:42:29.962 D/rgbTOxyz﹕ 0.16626617647060205
05-28 19:42:29.962 D/rgbTOxyz﹕ 0.16626617647060205 vs 0.16626617647060205
05-28 19:42:29.962 D/rgbTOxyz﹕ 2.354995989041693 vs 2.354995989041693
05-28 19:42:29.962 D/rgbTOlab﹕ 2.354995989041693 vs 2.036417989802886
05-28 19:42:29.962 D/QF﹕ 2.354995989041693

The value of rgb[0] should never change, I need it to be the same before and after that method call. Yet clearly the original argument is getting altered even though I'm never manipulating it or returning it. Any ideas on why this is happening, and how I can fix it? I'm at a total loss, any help is very much appreciated.

JinjerJohn
  • 403
  • 4
  • 6
  • Did you mean to clone `roi`? `double[] newroi = roi` declares a reference to double[] and initializes it to point to the same array as `roi` points to. – Patricia Shanahan May 29 '15 at 02:15

2 Answers2

1

When you pass arrays of primitive types into a function, it works the same way as for objects: A reference to the array will be passed, not the values directly, as it would be the case for single primitive values. For more infos, see this question.

That means, if you change the array inside the function as you did, it will happen on the memory block of the original array, effectively also changing the original array. roi, newroi and newrgb all point to the same memory block in your code.

To solve this problem, you have to explicitly copy the array, not only assign the reference to a new variable. Look into this method: Arrays.copyOf().

Community
  • 1
  • 1
TimoStaudinger
  • 41,396
  • 16
  • 88
  • 94
  • Thank you, that fixed it. I dropped that explicit copy and instead passed a copy of the array as the original argument. I had read up on how variables were passed, but I hadn't realized that arrays were objects and therefore treated differently. – JinjerJohn Jun 03 '15 at 19:10
0

This line double[] newroi = roi; doesn't create a new array, both variables refer to the same array so if you modify newroi[0], roi[0] will be modified too.

You should use Arrays.copyOf() or Object.clone() instead.

Bhullnatik
  • 1,263
  • 17
  • 28