views:

189

answers:

3

Hi! I have a code that need to be "translated" from C to Cpp, and i cant understand, where's a problem. There is the part, where it crashes (windows critical error send/dontSend):

 nDim = sizeMax*(sizeMax+1)/2;
 printf("nDim  = %d sizeMax = %d\n",nDim,sizeMax);
 hamilt = (double*)malloc(nDim*sizeof(double));
 printf("End hamilt alloc. %d allocated\n",(nDim*sizeof(double)));
 transProb = (double*)malloc(sizeMax*sizeMax*sizeof(double));
 printf("End transProb alloc. %d allocated\n",(sizeMax*sizeMax*sizeof(double)));
 eValues = (double*)malloc(sizeMax*sizeof(double));
 printf("eValues allocated. %d allocated\n",(sizeMax*sizeof(double)));
    eVectors  = (double**)malloc(sizeMax*sizeof(double*));
 printf("eVectors allocated. %d allocated\n",(sizeMax*sizeof(double*)));
 if(eVectors) for(i=0;i<sizeMax;i++) {
                 eVectors[i] = (double*)malloc(sizeMax*sizeof(double));
                 printf("eVectors %d-th element allocated. %d allocated\n",i,(sizeMax*sizeof(double)));
                 }
 eValuesPrev = (double*)malloc(sizeMax*sizeof(double));
 printf("eValuesPrev allocated. %d allocated\n",(sizeMax*sizeof(double)));
 eVectorsPrev  = (double**)malloc(sizeMax*sizeof(double*));
 printf("eVectorsPrev allocated. %d allocated\n",(sizeMax*sizeof(double*)));
 if(eVectorsPrev) for(i=0;i<sizeMax;i++) {
                     eVectorsPrev[i] = (double*)malloc(sizeMax*sizeof(double));
                     printf("eVectorsPrev %d-th element allocated. %d allocated\n",i,(sizeMax*sizeof(double)));
                     }

Log:

nDim  = 2485 sizeMax = 70
End hamilt alloc. 19880 allocated
End transProb alloc. 39200 allocated
eValues allocated. 560 allocated
eVectors allocated. 280 allocated 

So it crashes at the start of the loop of allocation. If i delete this loop it crashes at the next line of allocation. Does it mean that with the numbers like this i have not enough memory??

Thank you.

+1  A: 

You are probably not trying to allocate too much memory. Some other code has likely corrupted the heap and that can bite at just about any arbitrary point in the code afterwards. See the link for debugging aids.

If you were out of memory in a defect free program, malloc would return an error indication.

msw
+1  A: 

On my machine, this program compiles, executes without error and reports no memory problems when run through valgrind. Unless you are running on a small embedded system, your problem is likely something external to this code, because the total amount of memory allocated by this program is less than 140 KiB.

Besides, when malloc fails, it doesn't crash, it returns NULL. This code properly checks for eVectorsPrev being NULL, so there should be no NULL dereferencing problems here.

Tyler McHenry
>>is less than 140 KiB.exactly. Actually, before this there are some mallocation, but of the more or less same sizes. Tell me, please, are there some possibilities to see if i am out of memory? Or how can i "catch" the reason of the crash? And one more: i ve just noticed that the C-version is normally compiled by the same compiler of my DevC++ despite having the lines like hamilt = malloc(nDim*sizeof(double));without precision the type. Is it normal? Or i have occasion some strange compiler settings?
Andrew
sorry for the format, i dont understand how to do it in comments...
Andrew
The variables like `hamilt` must have their type declared *somewhere* otherwise it would not compile. They may be parameters of the function or globals. To detect memory corruption problems (which is what this most likely is) and/or to get a read on how much memory is being used, use a memory profiler/debugger. I use valgrind, but that's on Linux. This post has some good suggestions for valgrind-like tools for windows: http://stackoverflow.com/questions/413477/is-there-a-good-valgrind-substitute-for-windows
Tyler McHenry
yeah, the types are declared before. But what seems strange for me is that i was not able to compile the new version (also given to me on C) before precising the type for each malloc. But the previous one compiles. Where can be a difference?
Andrew
Oh, you're talking about the casts of `(double*)`, etc. on the `malloc` calls. In C this can be left out since `malloc` returns `void*` which implicitly converts to any pointer type. C++, being a different language, requires that you do an explicit conversion. However in C++, you really should be using `new[]` instead of `malloc`, or if you are going to use `malloc`, at least use `static_cast` instead of the C-style casts you posted.
Tyler McHenry
@andrew: heap corruption occurs at points sometimes very distant from the code that signals the corruption; adding new code can disclose heap corruption that happened in some completely unrelated code.
msw
A: 

What is sizeMax? I do not see the declaration, please fix the formatting. A side note... you are blindingly calling malloc without checking if it worked or not...that is a dangerous assumption - never assume there is plenty of memory available as the heap could become very fragmented and when a call to malloc for a very small object in a fragmented heap could fail as there is not enough memory...

tommieb75