Expression cannot be evaluated - why?

P

paul

Hi everyone,
I'm debugging an FFT routine and it has thrown up a perplexing error
which I cannot trace. Cannot anyone help? I've included the relevant
code below with comments:

rlft3(data_in1, speq_out1,1,512,256,1); // Perform FFT on 1st set of
input data

rlft3(data_in2, speq_out2,1,512,256,1); // Now 2nd set

// NB: data_in1/2, speq_out1/2 are indexed from 1
// data_in* are 3D arrays, speq_out* are 2D arrays

// data_in1[1][1][1] has "good data"

// Now do phase correlation

float *sp1, *sp2, r, im;
sp1 = &data_in1[1][1][1];
sp2 = &data_in2[1][1][1];

// data_in1[1][1][1] has "good data"


// Loop through elements multiplying and normalizing

for (int j=1;j<=(1*512*256)/2; j++)
{
r = sp1[0]*sp2[0] + sp1[1]*sp2[1];
im = sp1[1]*sp2[0] - sp1[0]*sp2[1];
sp1[0] = fac*r/sqrt(r*r + im*im);
sp2[1] = fac*im/sqrt(r*r + im*im);
sp1+=2;
sp2+=2;
}

// data_in1[1][1][1] has "good data"

// data_in1[1][1][1] has "good data"


// Do the same for the spectrum elements

sp1 = &speq_out1[1][1];
sp2 = &speq_out2[1][1];

for (j=1;j<=1024; j++)
{
r = sp1[0]*sp2[0] + sp1[1]*sp2[1];
im = sp1[1]*sp2[0] - sp1[0]*sp2[1];
sp1[0] = fac*r/sqrt(r*r + im*im);
sp2[1] = fac*im/sqrt(r*r + im*im);
sp1+=2;
sp2+=2;
}

int ab=1; // Does nothing - just put here for breakpoint purposes
// data_in1[1][1][1] is junk - "Expression cannot be evaluated" .

rlft3(data_in1, speq_out1, 1, 512, 256 , -1); // Do inverse FFT

Somewhere, the array data_in1 is being replaced by junk, although the
pointer value/memory address itself does not change. Whats happening?

TIA

Paul
 
R

Ron Natalie

Hi everyone,
I'm debugging an FFT routine and it has thrown up a perplexing error
which I cannot trace. Cannot anyone help? I've included the relevant
code below with comments:

rlft3(data_in1, speq_out1,1,512,256,1); // Perform FFT on 1st set of
input data

rlft3(data_in2, speq_out2,1,512,256,1); // Now 2nd set

You've NOT included the relevant code. Where is the declaration
of these functions. What is data_in1 declared as? What is Speq_out?
What are the definitions both in the caller and the claledd function?

You seem to pass in the size 512 256 1 but you don't use it at all in
the function.
What is fac?
// NB: data_in1/2, speq_out1/2 are indexed from 1
// data_in* are 3D arrays, speq_out* are 2D arrays

// data_in1[1][1][1] has "good data"

// Now do phase correlation

float *sp1, *sp2, r, im;
sp1 = &data_in1[1][1][1];
sp2 = &data_in2[1][1][1];

// data_in1[1][1][1] has "good data"
Why 1's here?

// Loop through elements multiplying and normalizing

for (int j=1;j<=(1*512*256)/2; j++)
{
r = sp1[0]*sp2[0] + sp1[1]*sp2[1];
im = sp1[1]*sp2[0] - sp1[0]*sp2[1];
sp1[0] = fac*r/sqrt(r*r + im*im);
sp2[1] = fac*im/sqrt(r*r + im*im);
sp1+=2;
sp2+=2;
}
Impossible to say, but my guess is you write off the end of the
allocation of the data_in1 and 2 arrays here.
// data_in1[1][1][1] has "good data"

// data_in1[1][1][1] has "good data"


// Do the same for the spectrum elements

sp1 = &speq_out1[1][1];
sp2 = &speq_out2[1][1];

for (j=1;j<=1024; j++)
{
r = sp1[0]*sp2[0] + sp1[1]*sp2[1];
im = sp1[1]*sp2[0] - sp1[0]*sp2[1];
sp1[0] = fac*r/sqrt(r*r + im*im);
sp2[1] = fac*im/sqrt(r*r + im*im);
sp1+=2;
sp2+=2;
}

int ab=1; // Does nothing - just put here for breakpoint purposes
// data_in1[1][1][1] is junk - "Expression cannot be evaluated" .

Possibly because there's a bug in this loop... again you possibly
write outside the allocation.
 
P

paul

The code in those functions isn't relevant, its just there because I
anticipated someone saying "what are you trying to do here?"

what I'm interested in is that somewhere between:

for (j=1;j<=1024; j++)
{
r = sp1[0]*sp2[0] + sp1[1]*sp2[1];
im = sp1[1]*sp2[0] - sp1[0]*sp2[1];
sp1[0] = fac*r/sqrt(r*r + im*im);
sp2[1] = fac*im/sqrt(r*r + im*im);
sp1+=2;
sp2+=2;
}

and:

rlft3(data_in1, speq_out1, 1, 512, 256 , -1);

the data_in1 array gets filled with duff data. Only theres nothing
there to change it. I've put breakdpoints in (I'm using VC++ 6) and
examined the quanities in the arrays
and they seem fine until just before the final rlft3(...) call.
 
T

Tom Widmer

The code in those functions isn't relevant, its just there because I
anticipated someone saying "what are you trying to do here?"

what I'm interested in is that somewhere between:

for (j=1;j<=1024; j++)
{
r = sp1[0]*sp2[0] + sp1[1]*sp2[1];
im = sp1[1]*sp2[0] - sp1[0]*sp2[1];
sp1[0] = fac*r/sqrt(r*r + im*im);
sp2[1] = fac*im/sqrt(r*r + im*im);
sp1+=2;
sp2+=2;
}

and:

rlft3(data_in1, speq_out1, 1, 512, 256 , -1);

the data_in1 array gets filled with duff data. Only theres nothing
there to change it. I've put breakdpoints in (I'm using VC++ 6) and
examined the quanities in the arrays
and they seem fine until just before the final rlft3(...) call.

Possibly you're writing past the end of an array or corrupting the stack
somewhere (possibly before this code is even called). You're the only
one who can see enough of the code to make a judgment - you haven't
posted nearly enough for anyone to have the first clue. For example, we
can't see declarations for data_in1 etc., so we can't work out whether
you're writing off the end of any of the arrays.

One general comment is that array indexing from 1 is a bad idea in C++
(and in programming in general IMHO).

Tom
 
P

paul

I agree that starting arrays from 1 is bad, but unfortunately this is
something of a legacy project inherited from formula in a book....which
were translated from fortran, and its 1-based arrays.

I'm still stumped.

The various arrays are defined as:

float *** data_in1=f3tensor(1,1,1,512,1,256); // width = 1...512,
height =1...256
float *** data_in2=f3tensor(1,1,1,512,1,256);

float **speq_out1 = matrix(1,1,1,1024);
float **speq_out2 = matrix(1,1,1,1024);


with the functions defined as:


#define NR_END 1

float ***f3tensor(long nrl, long nrh, long ncl, long nch, long ndl,
long ndh)
/* allocate a float 3tensor with range t[nrl..nrh][ncl..nch][ndl..ndh]
*/
{
long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1,ndep=ndh-ndl+1;
float ***t;

/* allocate pointers to pointers to rows */
t=(float ***) malloc((size_t)((nrow+NR_END)*sizeof(float**)));
//if (!t) nrerror("allocation failure 1 in f3tensor()");
t += NR_END;
t -= nrl;

/* allocate pointers to rows and set pointers to them */
t[nrl]=(float **) malloc((size_t)((nrow*ncol+NR_END)*sizeof(float*)));
//if (!t[nrl]) nrerror("allocation failure 2 in f3tensor()");
t[nrl] += NR_END;
t[nrl] -= ncl;

/* allocate rows and set pointers to them */
t[nrl][ncl]=(float *)
malloc((size_t)((nrow*ncol*ndep+NR_END)*sizeof(float)));
//if (!t[nrl][ncl]) nrerror("allocation failure 3 in f3tensor()");
t[nrl][ncl] += NR_END;
t[nrl][ncl] -= ndl;

for(j=ncl+1;j<=nch;j++) t[nrl][j]=t[nrl][j-1]+ndep;
for(i=nrl+1;i<=nrh;i++) {
t=t[i-1]+ncol;
t[ncl]=t[i-1][ncl]+ncol*ndep;
for(j=ncl+1;j<=nch;j++) t[j]=t[j-1]+ndep;
}

/* return pointer to array of pointers to rows */
return t;
}



float **matrix(long nrl, long nrh, long ncl, long nch)
/* allocate a float matrix with subscript range m[nrl..nrh][ncl..nch]
*/
{
long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
float **m;

/* allocate pointers to rows */
m=(float **) malloc((size_t)((nrow+NR_END)*sizeof(float*)));
//if (!m) nrerror("allocation failure 1 in matrix()");
m += NR_END;
m -= nrl;

/* allocate rows and set pointers to them */
m[nrl]=(float *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(float)));
//if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
m[nrl] += NR_END;
m[nrl] -= ncl;

for(i=nrl+1;i<=nrh;i++) m=m[i-1]+ncol;

/* return pointer to array of pointers to rows */
return m;
}
 
T

Tom Widmer

I agree that starting arrays from 1 is bad, but unfortunately this is
something of a legacy project inherited from formula in a book....which
were translated from fortran, and its 1-based arrays.

I'm still stumped.

The various arrays are defined as:

float *** data_in1=f3tensor(1,1,1,512,1,256); // width = 1...512,
height =1...256
float *** data_in2=f3tensor(1,1,1,512,1,256);

float **speq_out1 = matrix(1,1,1,1024);
float **speq_out2 = matrix(1,1,1,1024);


with the functions defined as:


#define NR_END 1

float ***f3tensor(long nrl, long nrh, long ncl, long nch, long ndl,
long ndh)
/* allocate a float 3tensor with range t[nrl..nrh][ncl..nch][ndl..ndh]
*/
{
long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1,ndep=ndh-ndl+1;
float ***t;

/* allocate pointers to pointers to rows */
t=(float ***) malloc((size_t)((nrow+NR_END)*sizeof(float**)));
//if (!t) nrerror("allocation failure 1 in f3tensor()");
t += NR_END;
t -= nrl;

/* allocate pointers to rows and set pointers to them */
t[nrl]=(float **) malloc((size_t)((nrow*ncol+NR_END)*sizeof(float*)));
//if (!t[nrl]) nrerror("allocation failure 2 in f3tensor()");
t[nrl] += NR_END;
t[nrl] -= ncl;

/* allocate rows and set pointers to them */
t[nrl][ncl]=(float *)
malloc((size_t)((nrow*ncol*ndep+NR_END)*sizeof(float)));
//if (!t[nrl][ncl]) nrerror("allocation failure 3 in f3tensor()");
t[nrl][ncl] += NR_END;
t[nrl][ncl] -= ndl;

for(j=ncl+1;j<=nch;j++) t[nrl][j]=t[nrl][j-1]+ndep;
for(i=nrl+1;i<=nrh;i++) {
t=t[i-1]+ncol;
t[ncl]=t[i-1][ncl]+ncol*ndep;
for(j=ncl+1;j<=nch;j++) t[j]=t[j-1]+ndep;
}

/* return pointer to array of pointers to rows */
return t;
}


Yikes, all that just so you can use the syntax a[j][k]. But there's
an easier (or at least safer) way - C++ operator overloading. Obviously,
verifying that the above code is correct is not easy by inspection
(though it looks correct), because a simple out by one error anywhere is
likely to spell disaster. In general, such code should be avoided like
the plague.

Going back to your original code, one thing jumps out:

for (j=1;j<=1024; j++)
{
r = sp1[0]*sp2[0] + sp1[1]*sp2[1];
im = sp1[1]*sp2[0] - sp1[0]*sp2[1];
sp1[0] = fac*r/sqrt(r*r + im*im);
sp2[1] = fac*im/sqrt(r*r + im*im);
sp1+=2;
sp2+=2;
}

That appears to be writing off the end of your matrices (it's writing to
&speq_out1[1][1] + 2048 I think, while +1024 is actually the last
value), and presumably hosing the value of data_in1 in the process.

Tom
 
P

paul

Going back to your original code, one thing jumps out:

for (j=1;j<=1024; j++)
{
r = sp1[0]*sp2[0] + sp1[1]*sp2[1];
im = sp1[1]*sp2[0] - sp1[0]*sp2[1];
sp1[0] = fac*r/sqrt(r*r + im*im);
sp2[1] = fac*im/sqrt(r*r + im*im);
sp1+=2;
sp2+=2;
}

That appears to be writing off the end of your matrices (it's writing to
&speq_out1[1][1] + 2048 I think, while +1024 is actually the last
value), and presumably hosing the value of data_in1 in the process.
I've changed it to:


for (j=1;j<1024 + 1; j++)
{
r = sp1[0]*sp2[0] + sp1[1]*sp2[1];
im = sp1[1]*sp2[0] - sp1[0]*sp2[1];
sp1[0] = fac*r/sqrt(r*r + im*im);
sp2[1] = fac*im/sqrt(r*r + im*im);
sp1+=2;
sp2+=2;
}

- and it still doesn't work!
 
T

Tom Widmer

Going back to your original code, one thing jumps out:

for (j=1;j<=1024; j++)
{
r = sp1[0]*sp2[0] + sp1[1]*sp2[1];
im = sp1[1]*sp2[0] - sp1[0]*sp2[1];
sp1[0] = fac*r/sqrt(r*r + im*im);
sp2[1] = fac*im/sqrt(r*r + im*im);
sp1+=2;
sp2+=2;
}

That appears to be writing off the end of your matrices (it's writing to
&speq_out1[1][1] + 2048 I think, while +1024 is actually the last
value), and presumably hosing the value of data_in1 in the process.
I've changed it to:


for (j=1;j<1024 + 1; j++)
{
r = sp1[0]*sp2[0] + sp1[1]*sp2[1];
im = sp1[1]*sp2[0] - sp1[0]*sp2[1];
sp1[0] = fac*r/sqrt(r*r + im*im);
sp2[1] = fac*im/sqrt(r*r + im*im);
sp1+=2;
sp2+=2;
}

- and it still doesn't work!

That's not changed anything! How is <1024+1 any different to <=1024?
It's still writing out to &speq_out1[1][1] + 2048. That's 1024 float
elements off the end of the allocated storage AFAICT, hosing 4K of heap.
Perhaps the loop should have <=512 as the condition? Only you can say,
but it's definitely wrong at the moment.

Tom
 
P

paul

I've checked the code and it seems to be OK. The memory reserved for
the four arrays don't overlap so theres no chance of any memory being
overwritten.

I'm bewildered. Its almost as if you go to a light swittch, turn it on
and off dozens of times, go to a sofa, read a book and the light turns
on by itself! Perhaps theres a ghost in the machine.... :)
 
T

Tom Widmer

I've checked the code and it seems to be OK. The memory reserved for
the four arrays don't overlap so theres no chance of any memory being
overwritten.

Of course the memory doesn't overlap, but if you write off the end of an
array, you might hit one of the other arrays (or any other heap memory
for that matter).
I'm bewildered. Its almost as if you go to a light swittch, turn it on
and off dozens of times, go to a sofa, read a book and the light turns
on by itself! Perhaps theres a ghost in the machine.... :)

I've already told you the problem. You have this code:

float **speq_out1 = matrix(1,1,1,1024);
float **speq_out2 = matrix(1,1,1,1024);

So &speq_out1[1][1] is a pointer to the first of 1024 floats (from
looking at your matrix function).

sp1 = &speq_out1[1][1];
sp2 = &speq_out2[1][1];

So sp1 is a pointer to the first of 1024 floats.

for (j=1;j<=1024; j++)
{
r = sp1[0]*sp2[0] + sp1[1]*sp2[1];
im = sp1[1]*sp2[0] - sp1[0]*sp2[1];
sp1[0] = fac*r/sqrt(r*r + im*im);
sp2[1] = fac*im/sqrt(r*r + im*im);
sp1+=2;

Here, sp1 is incremented by *2*. This happens 1024 times.

sp2+=2;
}

Hence on the final loop, you write to (&speq_out1[1][1])[2046]. BOOM!

Tom
 
T

Tom Widmer

But it isn't speq1 thats causing problems - its data_in1 !

Writing off the end of speq1 may well involve overwriting data_in1!
They may well be placed sequentially in memory.

Incidentally, do you ever free the memory allocated by "matrix" etc.?
If not, you should, and it may show up some other heap corruption bugs
elsewhere in the code.

Tom
 
O

Old Wolf

Tom said:
Incidentally, do you ever free the memory allocated by "matrix" etc.?
If not, you should, and it may show up some other heap corruption bugs
elsewhere in the code.

The memory was allocated by:

Freeing that is going to be a whole lotta fun.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top