Fatal error in ~NRmatrix() compiled by VS9


xishi
05-18-2008, 07:43 AM
Hello,

The first line in ~NRmatrix() in nr3.h
"delete [] (v[0])",
always cause a fatal error complied by VC9.
The error information is like:
"CRT detected that the application wrote to memory after end of heap buffer."
If I forbide this line, there's no error, but the ocupied memory won't be realsed either.
Who can tell me how to solve this problem?
Thank you!
Xi Shi

davekw7x
05-18-2008, 09:10 AM
The first line in ~NRmatrix() in nr3.h
delete [] (v[0])
always cause a fatal error complied by VC9.
Well, the first line in ~NRmatrix() in my nr3.h is

if (v != NULL) {


This is from the Numerical Recipes CD. Where did you get your nr3.h?


The error information is like...
Assuming that your nr3.h has the correct information as I showed above, this probably indicates that somewhere in your program you wrote beyond the end of an allocated array (VecDoub or MatDoub, for example). There are other things that might corrupt memory in such a way as to cause error messages like yours, but I think that this is the most common.

Can you show us a simple (short) example program that shows this problem on your system?

Or, you can try the following program and tell us what happens:

#include "../code/nr3.h"

int main()
{
MatDoub e(3,3);
e[0][0]=1;
e[0][1]=2;
e[0][2]=3;
e[1][0]=4;
e[1][1]=5;
e[1][2]=6;
e[2][0]=7;
e[2][1]=8;
e[2][2]=9;

for (int i = 0; i < e.nrows(); i++) {
for (int j = 0; j < e.ncols(); j++) {
cout << "e[" << i
<< "][" << j << "] = "
<< e[i][j] << " ";
}
cout << endl;
}
return 0;
}


Results on my Windows XP system after using Microsoft Visual C++ Express Edition 2008, which is the free download version of the VS9 compiler and Integrated Development Environment (and lots of other compilers that I play with, from time to time):

e[0][0] = 1 e[0][1] = 2 e[0][2] = 3
e[1][0] = 4 e[1][1] = 5 e[1][2] = 6
e[2][0] = 7 e[2][1] = 8 e[2][2] = 9


If this works for you, then look carefully at your code to see whether your program has ever gone beyond the end of any of your dynamically allocated arrays or has done any other illegal memory accesses (with pointers of any kind, for example).

Regards,

Dave

xishi
05-18-2008, 07:58 PM
Thank you, Dave.

my code:

// ImageCD.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "ImageCD.h"
.................
#include "ImageChangeDetection.h"
#include "nr3.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif
//#define ZEROS 0;
//#define ONES 1;
//#define WM_MY_MESSAGE(WM_USER+100)

// CImageCDApp

BEGIN_MESSAGE_MAP(CImageCDApp, CWinApp)
ON_COMMAND(ID_APP_ABOUT, &CImageCDApp::OnAppAbout)
// Standard file based document commands

// Standard print setup command
ON_COMMAND(ID_FILE_PRINT_SETUP, &CWinApp::OnFilePrintSetup)
ON_COMMAND(ID_FILE_OPEN_REF, &CImageCDApp::OnFileOpenRef)
ON_COMMAND(ID_OPEN_FILE_TES, &CImageCDApp::OnOpenFileTes)
ON_COMMAND(ID_IMCDETECTION_SIMPLEDIFFERENCE, &CImageCDApp::OnImcdetectionSimpledifference)
ON_COMMAND(ID_IMCDETECTION_LIKLYHOODRAT, &CImageCDApp::OnImcdetectionLiklyhoodrat)
ON_COMMAND(ID_IMCDETECTION_SETPARAMETERS, &CImageCDApp::OnImcdetectionSetparameters)
ON_UPDATE_COMMAND_UI(ID_IMCDETECTION_SIMPLEDIFFERE NCE, &CImageCDApp::OnUpdateImcdetectionSimpledifference)
ON_UPDATE_COMMAND_UI(ID_IMCDETECTION_LIKLYHOODRAT, &CImageCDApp::OnUpdateImcdetectionLiklyhoodrat)
ON_COMMAND(ID_ICDALGORITHM_LINEARDEPEND, &CImageCDApp::OnIcdalgorithmLineardepend)
ON_UPDATE_COMMAND_UI(ID_ICDALGORITHM_LINEARDEPEND, &CImageCDApp::OnUpdateIcdalgorithmLineardepend)
ON_COMMAND(ID_PREDICTIVESPATIALMODEL_QUADRATICMODE L, &CImageCDApp::OnPredictivespatialmodelQuadraticmode l)
END_MESSAGE_MAP()


// CImageCDApp construction

............

void CImageCDApp::OnImcdetectionSimpledifference()
{
//float* diff;
//diff = simpledifference();
//diff[1,1]=2;
// TODO: Add your command handler code here
int m,n;

m = ImageCDPublicVariables::ref_Image->GetHeight();
n = ImageCDPublicVariables::ref_Image->GetWidth();

MatDoub diff(m,n);
simpledifference(diff);

CImage *Im=new CImage;
Im->Create(diff.nrows(),diff.ncols(),8,0);
//double sigma0, sigma1,mean0;

conversion(diff,Im);
CString inf;
inf = "Simple Difference";
ShowTheImageMatrix(Im,inf);
}//****
..................



There's no error until the application runs to the last line (****).
If I forbide the 'delete [](v[0])' in ~Nrmatrix(), there will be no such error reports.
What's the problem?
Thank you.

davekw7x
05-19-2008, 12:30 AM
my code:

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

Are you running this with _DEBUG defined? I suggest that comment out the stuff defining the new macro. If that macro is from Microsoft, I'm guessing it isn't causing this particular problem (corrupting memory), but I have seen bad experiences with re-defined new operators from time to time.

Sidenote: There also appears to be a memory leak, since you apparently allocate storage for Im but don't appear to de-allocate it. Of course we have no way of knowing what really happens with it.) I seriously doubt that it leads to the error you showed, but it is a bug. I just thought I would mention it.



So, assuming that not defining _DEBUG and after fixing the memory leak did not fix the problem:


In your very first post you said:
The first line in ~NRmatrix() in nr3.h
"delete [] (v[0])",
always cause a fatal error complied by VC9.
The point I was trying to make is that the NRMatrix destructor does ***not*** always cause a fatal error on my system, and I gave an example program.

I have mentioned that, in my experience, there are a number of things in a user program that could corrupt memory in such a way that a delete operator can cause a program crash.


Here goes:

You allocate a MatDoub called diff. You call two functions with diff as an argument. Since we have no way of knowing what happens inside the functions we can hardly debug your program. (I assume they are 'call by reference' but, again, we have no way of knowing.) If your program writes beyond the end of the array (or even some other array or pointer value that was obtained by dynamic memory allocation), then that could cause the program to bomb when the array goes out of scope at the end of the function and the destructor is invoked. See footnote.

When I suggested that you create a simple (small) program that shows this error, I guess you didn't understand. The point is to get you to boil it down to something that you can show us so that we can actually help you. Sometimes that is very difficult, I know, but I think it is worthwhile.

Have you tested the functions diff() and conversion() separately? Maybe you could show us the code?

Bottom line: You simply have not shown us enough for me to understand how many ways things could go wrong.

Maybe someone else...


Regards,

Dave

Footnote: go back to my example. Add the following line after the other assignment statements:


e[3][0]=10;


Now this leads to undefined behavior. You might or might not get an error, so it doesn't really prove anything. Depending on your compiler, you might see an error message similar to your program's problem (or, maybe not). It might be interesting to try. If it doesn't give the same kind of error, then we haven't learned anything. On the other hand if it does lead to the same bad behavior, then it might illustrate the point that I tried to make.

Of course you may have to modify my test program to compile it under the same conditions as your application. (Make it a Windows program instead of command-line, for example.)

xishi
05-20-2008, 01:09 AM
Thank you, Dave.
you are right, the problem lies in the diff() funtion.