Cannot recover data defined in a subroutine

Hi there. I obviously count on @keskiverto to crack it. I don't know if I should have edited it? I was afraid I would miss/drop something important. In short, the issue here that I define a three dimensional array in the first routine and when I check with gdb I can find all the correct values in the arrays (statement 66) but nothing come out on the outside and I get a "Cannot access memory at address 0xc28348c308c48348" or similar at the 5th statement in the calling routine. I have other routines with only two dimensions in similar situations and they seem to work. What is wrong with three dimensions?

Thanks.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// .........................
    int ll_min = 2,ll_max = 30, phiDiv = 100;
    double ***legendreCoeff_Only;
    legendreTransfOnly (NN, ll_min, ll_max, phiDiv, legendreCoeff_Only, PhiBounds);
    legendreOnly_Restore (NN, ll_min, ll_max, phiDiv, legendreCoeff_Only, PhiBounds);
  }    //  integrateNONrotated // Class RealWork
  

  public : void legendreTransfOnly (int NN, int ll_min, int ll_max, int phiDiv, double ***legendreCoeff_Only, PhiLimits *PhiBounds)
{
    // dimensions of legendreCoeff_Only: 
    // (1) angle phi in 0.9 degrees increments from 0 to 90 degrees, represented by phiCou (integer)
    // (2) index ll
    // (3) index mm
    Conversions conv;
    LegendrePolynomials leg;
    Localizations loc;
    std::ofstream outFile_1,outFile_2;
    outFile_1.open ("fileLeg_Coeff.csv");
    outFile_2.open ("fileInsideH.csv");
    double * flatAreasArray;
    double flatHere;
    int phiCou,hTest;
    double phi,phiRad,phiStep,theta,thetaRad,cosTheta,xx,yy,zz,res,ALP,weight;
    phiStep = 90.00/phiDiv;  // phiDiv is 100
    legendreCoeff_Only = new double ** [phiDiv+1];
    phi = - phiStep;
    phiCou = -1;
    while (phi <= 90.0) {
      phi += phiStep;
      phiCou += 1;
      legendreCoeff_Only[phiCou] = new double * [ll_max - ll_min + 1]; 
      outFile_1 << "phi = " << phi << "\n";
      outFile_2 << "phi = " << phi << "\n";
      phiRad = conv.degToRad (phi);
      for (int ll = ll_min; ll <= ll_max; ll++) {
        legendreCoeff_Only [phiCou][ll-ll_min] = new double [ll+1];
        flatAreasArray = new double[ll+1];
        if (ll > 0)          
          readFlatAreas (ll,flatAreasArray);
        else
          flatAreasArray[0] = 0.0;         
        outFile_1 << "ll = " << ll << ",";
        outFile_2 << "ll = " << ll << ",";
        for (int mm = 0; mm <= ll; mm++) {
          flatHere = flatAreasArray [mm];          
          res = 0.0;
          for (int jj = ComCom.thetaIntMinn; jj <= ComCom.thetaIntMaxx; jj++)  {   // Theta loop
            theta = PhiBounds[jj].theta;
            if (theta > flatHere) {
              thetaRad = conv.degToRad(theta);  
              cosTheta = cos(thetaRad); 
              conv.convToCart (thetaRad,phiRad,xx,yy,zz); 
              hTest = loc.insideLetterH (xx,yy,zz);                          // This checks if inside letter H.
              outFile_2 << hTest << ",";
              if (hTest == 1 || hTest == 2 || hTest == 3) {
                ALP = leg.legendre_Norm_Selector (cosTheta,ll,mm,2);
                weight = loc.findWeight (NN,jj);
                res += (ALP * weight);
              } 
            }
          }               // theta loop
          outFile_1 << res << ",";          
          legendreCoeff_Only[phiCou][ll-ll_min][mm] = res;
        }                 // mm loop
        outFile_1 << "\n";
        outFile_2 << "\n";
      }                   // ll loop
      free (flatAreasArray);
      outFile_2 << "\n";
    }                     // phi loop
    outFile_1.close();
    outFile_2.close();
}                               // legendreTransfOnly  class RealWork


public : void legendreOnly_Restore (int NN, int ll_min, int ll_max, int phiDiv, double ***legendreCoeff_Only, PhiLimits *PhiBounds)
  {
    Conversions conv;
    LegendrePolynomials leg;
    Localizations loc;
    std::ofstream outFile_3,outFile_4;
    outFile_3.open ("perspectProj_3.dat");
    outFile_4.open ("fileLegOnlyRestore.csv");
    double * flatAreasArray;
    double flatHere;
    int phiCou;
    double phi,phiRad,phiStep,theta,thetaRad,cosTheta,xx,yy,zz,res,ALP,weight,coeff;
    phiStep = 90.00/phiDiv;  // phiDiv is 100
    phi = - phiStep;
    phiCou = -1;
    while (phi <= 90.0) {
      phi += phiStep;
      outFile_4 << endl << "phi = " << phi;
      phiCou += 1;
      phiRad = conv.degToRad (phi);
      for (int jj = ComCom.thetaIntMinn; jj <= ComCom.thetaIntMaxx; jj++)  {   // Theta loop
        theta = PhiBounds[jj].theta;
        thetaRad = conv.degToRad(theta); 
        conv.convToCart (thetaRad,phiRad,xx,yy,zz);          
        cosTheta = cos(thetaRad); 
        res = 0.0;
        for (int ll = ll_min; ll <= ll_max; ll++) {
          for (int mm = 0; mm <= ll; mm++) {
            ALP = leg.legendre_Norm_Selector (cosTheta,ll,mm,2);
            coeff = legendreCoeff_Only[phiCou][ll-ll_min][mm];
            if (coeff > 0.0)
              res += (ALP * coeff);
          }
        } 
        outFile_4 << res << ",";
      }
    }
    outFile_3.close();
    outFile_4.close();
  }                              // legendreOnly_Restore   class RealWork 

Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>

void bar ( int* x ) {
  x = new int;
  delete x;
  if ( x ) std::cout << "x is invalid, but not null\n";
}

int main() {
  int * fubar = nullptr;
  bar( fubar );
  if ( fubar ) std::cout << "Will you see me?\n";
  return 0;
}

The x is a by value parameter. A copy.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>

void bar ( int* & y ) {
  y = new int;
  delete y;
  if ( y ) std::cout << "y is invalid, but not null\n";
}

int main() {
  int * fubar = nullptr;
  bar( fubar );
  if ( fubar ) std::cout << "Will you see me?\n";
  return 0;
}

The y is fubar.
Last edited on
Although I don't understand your cryptic message, I think I figured out what I should do. I have to define the sizes of all three dimensions before I call the routines. I certainly can do it. Thanks, - Alex
Well.

You do pass a pointer to the function:
1
2
double ***legendreCoeff_Only;
legendreTransfOnly (NN, ll_min, ll_max, phiDiv, legendreCoeff_Only, PhiBounds);

and you clearly expect the function to change that pointer of the caller:
1
2
3
4
public : void legendreTransfOnly (int NN, int ll_min, int ll_max, int phiDiv, double ***FOO, PhiLimits *PhiBounds)
{
  // code 
  FOO = new double ** [phiDiv+1];

That does not happen!

The FOO is a function local variable that is merely initialized with the value of legendreCoeff_Only. A copy. (And legendreCoeff_Only is uninitialized too.)

The legendreCoeff_Only of the caller does not change when you change FOO.

When you call legendreOnly_Restore(), you again pass the same (uninitialized) pointer. Crash.

Therefore, you should change the signature of legendreTransfOnly() into:
void legendreTransfOnly(int NN, int ll_min, int ll_max, int phiDiv, double *** & FOO, PhiLimits *PhiBounds)
If you do that, then the FOO is a reference and assigning to it effectively assigns to legendreCoeff_Only of the caller.
Last edited on
Thank you @keskiverto, you are a great guy. I will try it.
Last edited on
Needless to say everything works!!! Viva @Keskiverto!!!
Last edited on
Topic archived. No new replies allowed.