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 12 8041 pa**@paullee.com wrote:
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.
>
rlft3(data_in1, speq_out1, 1, 512, 256 , 1); // Do inverse FFT
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. pa**@paullee.com wrote:
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
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 1based 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=nrhnrl+1,ncol=nchncl+1,ndep=ndhndl+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(flo at)));
//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][j1]+ndep;
for(i=nrl+1;i<=nrh;i++) {
t[i]=t[i1]+ncol;
t[i][ncl]=t[i1][ncl]+ncol*ndep;
for(j=ncl+1;j<=nch;j++) t[i][j]=t[i][j1]+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=nrhnrl+1,ncol=nchncl+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[i]=m[i1]+ncol;
/* return pointer to array of pointers to rows */
return m;
} pa**@paullee.com wrote:
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 1based 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=nrhnrl+1,ncol=nchncl+1,ndep=ndhndl+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(flo at)));
//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][j1]+ndep;
for(i=nrl+1;i<=nrh;i++) {
t[i]=t[i1]+ncol;
t[i][ncl]=t[i1][ncl]+ncol*ndep;
for(j=ncl+1;j<=nch;j++) t[i][j]=t[i][j1]+ndep;
}
/* return pointer to array of pointers to rows */
return t;
}
Yikes, all that just so you can use the syntax a[i][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
>
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! pa**@paullee.com wrote:
>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
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.... :) pa**@paullee.com wrote:
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
But it isn't speq1 thats causing problems  its data_in1 ! pa**@paullee.com wrote:
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
Tom Widmer wrote:
>
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:
> m=(float **) malloc((size_t)((nrow+NR_END)*sizeof(float*))); m += NR_END; m = nrl;
Freeing that is going to be a whole lotta fun. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Paul Rubin 
last post by:
OK, I want to scan a file for lines matching a certain regexp. I'd
like to use an assignment expression, like
for line in file:
if (g := re.match(pat, line)):
croggle(g.group(1))
Since...

by: Joăo Santa Bárbara 
last post by:
Hi all
this message ( Expression cannot be evaluated at this time. ) apears when i
in the debug window do this
?xdrMaster("field1")
can some one help me ..
JSB

by: MLH 
last post by:
Am repeating question with different subject heading, perhaps
stating more clearly my problem...
I have an A97 query (qryVehiclesNowners2) that has a table
field in it named . Depending on the...

by: lp 
last post by:
While debugging an application, whenever i enter into a specific function,
all watch values refering to this function get the error message:
"Expression Cannot Be evaluated at this Time". The...

by: Suresh Jeevanandam 
last post by:
Dear all,
I read in "Python in a Nutshell" that when we have multiple assignments
made on a single line, it is equivalent to have those many simple
assignments and that the right side is evaluated...

by: paul 
last post by:
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,...

by: Steven T. Hatton 
last post by:
I'm trying to improve my formal understanding of C++. One significant part
of that effort involves clarifying my understanding of the vocabulary used
to describe the language.
This is from the...

by: silpau 
last post by:
hi,
i am a bit confused on expression evaluation order in expressions
involving unary increment.decrement operators along with binary
operators.
For example in the following expression
x...

by: Jeff Bean 
last post by:
I need to compute a 64 bit file offset which will get passed to the _lseeki64 function.
The inputs to the offset calculation are all unsigned shorts or unsigned longs. For example:
unsigned...

by: isladogs 
last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
In this month's session, Mike...

by: veera ravala 
last post by:
ServiceNow is a powerful cloudbased platform that offers a wide range of services to help organizations manage their workflows, operations, and IT services more efficiently. At its core, ServiceNow...

by: VivesProcSPL 
last post by:
Obviously, one of the original purposes of SQL is to make data query processing easy. The language uses many Englishlike terms and syntax in an effort to make it easy to learn, particularly for...

by: jianzs 
last post by:
Introduction
Cloudnative applications are conventionally identified as those designed and nurtured on cloud infrastructure. Such applications, rooted in cloud technologies, skillfully benefit from...

by: jimatqsi 
last post by:
The boss wants the word "CONFIDENTIAL" overlaying certain reports. He wants it large, slanted across the page, on every page, very light gray, outlined letters, not block letters. I thought Word Art...

by: isladogs 
last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM).
In this month's session, the creator of the excellent VBE...

by: stefan129 
last post by:
Hey forum members, I'm exploring options for SSL certificates for multiple domains. Has anyone had experience with multidomain SSL certificates? Any recommendations on reliable providers or specific...

by: egorbl4 
last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это
Что это? Что мне с этим делать?
...

by: MeoLessi9 
last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
 