Re: Mex Overflow Error Using Free Borland Compiler



Rune Allnor wrote:
> usenetseu3@xxxxxxxxx wrote:
>
>>Hi All,
>>I need help eliminating the source of the following Mex runtime error.
>>Any question, suggestion, or criticism would be extremely helpful.
>>
>>I encounter this error when I execute a Mex file I programmed in C:
>> "pow: OVERFLOW error"
>>Matlab crashes unless I close all 70 or so dialog boxes that pop up
>>with this error, which suggests to me that the problem is with how the
>>Borland compiler handles overflow errors. Is this a correct assumption?
>
>
> We checked this out in a different subthread. at leats at first glance,
>
> there was no help in tweaking the numerical exception handling
> in the Borland compiler. It might not have been irrelevant, but
> it was not the main cause of your problems.
>
>
>>The reason why I'm running into this problem is obvious to me; my Mex
>>file contains unavoidably complicated equations representing the 3D
>>dynamics of an object that I am simulating. On the other hand,
>>"complicated equations" is no reason to give up on research, and so I'm
>>looking for ways to simulate this object without having Matlab crash on
>>me. I've been unsuccessful so far, and need help from a more
>>experienced programmer than I.
>>
>>The first thing I tried is dynamic memory allocation. Other posts in
>>this newsgroup suggested mxCalloc was the way to go, but this didn't
>>work for me. My first question is: what's wrong with how I'm using
>>mxCalloc? Relevant code snippets are at the very end of this post.
>
>
> One criticism against your program, is that I wouldn't use mxCalloc
> for internal variables, only for those that will be returned back
> to the matlab workspace after the CMEX program has terminated.
> Use MALLOC/CALLOC to allocate iunternal variables if you
> program C, NEW if you program C++. And don't forget to delete
> those variables before your program returns to matlab!

Why not use mxCalloc or the like? They work just fine. That's an opinion and
shouldn't be a criticism. I would however have 2 notes on the original code
which is:
1- You declare the variables of type double and allocate of size long double.
2- If these are scalars, why allocate the memory? You allocate 1 of each. This
would clean up a lot of code by eliminating the pointer dereferences.

>
>
>>Secondly: does anyone have any other suggestions on how to avoid this
>>overflow error? I had thought that dynamic memory allocation would
>>solve the issue.
>
>
> Dynamic memory allocation might make it worse. "Wild pointers" are
> infamous problems in C and C++, and might cause the type of problems
> you see. A "wild pointer" is a pointer that does not point to where you
>
> think it points, so it may introduce garbage numbers into your
> computations. Another type of error associated with "wild pointers"
> is the "segmentation violation" error. This happens when the ponter
> attempts to access memory that has not been allocated by the OS.

My suggestion would be to set pointers to NULL after freeing them.

>
> Another possible cause of these types of errors is that you have not
> initialized the memory you allocate. MALLOC and CALLOC assign
> a segment of memory to one variable, accessible through a pointer,
> but they do not prepare the segment of memory for use. So if you
> attempts to read from an allocated but not initialized variable,
> you end up introducing garbage in your computations.
>
> So to be safe, every time you allocate some memory by MALLOC
> or similar, run through the array and set all floats to 0.

Although not guaranteed by the standard, many platforms have all bit 0
representation for floating point 0.0 in which case mxCalloc (which the OP used)
would initialize all the data to 0. Just to iterate again though, it's not
guaranteed by the standard and should not be relied on.

>
>
>>I am compiling my Mex file in Matlab 7 R14 with the free Borland C++
>>compiler v5.5.1. The Matlab lcc compiler would not compile my
>>equations. Has anyone encountered this error before, and have any
>>suggestions on how to proceed?
>
>
> This is and indication that there are some syntax errors or structural
> errors in your code. I would suggest you make an effort to enforce some
>
> standard programming style to your programs. C and C++ are very
> wide spread, lots of people sell compilers, and all make their own
> twists and extensions to the programming language. This makes
> it difficult to port programs from one system to another, some times
> even between compilers on the same system.

The OP should post the errors produced by lcc to determine why lcc wouldn't
compile the code. Perhaps it's becuase C is case sensitive and you used Cos
instead of cos and I do not know what Power is. Perhaps you meant pow in math.h?

>
> To avoid such problems, there exists a standard for the C language,
> "ANSI C", that specifies what ought to be a common mutual basis
> for all C and C++ compilers. I have found that life is a lot easier
> when I stay within the ANSI standard. I miss out on some of the
> nifty peculiarities of this and that compiler, but when I have a
> working program, it compiles and runs everywhere.
>
>
>>My fourth and last question: can anyone
>>suggest a better (freely available) compiler for my Mex files?
>
>
> No, lcc ought to be OK. Maybe not optimal, but more than good
> enough. I think your problem has more to do with the C code
> itself and not the compiler.

You can try the GNU C compiler available on mingw or cygwin.

>
>
>>As I said earlier, any small suggestion would probably be extremely
>>helpful, especially as I'm new to both Mex and C programming.
>
>
> I found one line in your code below, that worries me:
>
> *x7dotdot = (l*(4**x6dot**x7dot*M*(-1 + ...
>
> Maybe this is well-defined in the C language, but it might not be.
> The problem is "operator precedence". You may not have heard the
> term before, but you are alreday familiar with the idea from basic
> maths.

This is well defined in C. In ISO C99 section 6.5.5 (Multiplicative Operators)
the Constraints are then both operands shall have arithmetic type. The operands
of the % operator shall have integer types. therefore the compiler cannot
interpret constant * * pointer as the multiplication of a pointer.

>
> If you have an expression like
>
> x = a*b+c
>
> you know that the two numbers a and b are supposed to be multiplied
> before the number c is added. If the "+" and "*" operations are done in
>
> the reversed order, the result is different. If you want the operations
>
> to be done in the reversed order, you have to indicate it:
>
> y = a*(b+c)
>
> But this "operator presedence" is not alway important. The expression
>
> z = a + b - c
>
> can be implemented either as
>
> z1 = (a + b) - c
>
> or
>
> z2 = a + (b - c)
>
> but it does not matter since z1 == z2.
>
> In your program you have a construct like
>
> float *a;
> float b;
> float x;
>
> /* initializations */
>
> x = b**a;
>
> To me, as a human reader, it is obvious that you want x to contain
> b times the number contained in the memory location a points to.
> There is a *slight* chance that some compilers can be confused into
> thinking this means "multiply the pinter a by b, and use the numebr
> that is kept in the new memory location",
>
> x = *(b*a);

This totally changes the expression. You've moved an operator to the other side
of an operand.


>
> IF it turns out that the pointer dereference operatoe and the number
> multiply operator are at the same level in the operator hierarchy
> (I find it hard to believe, but I don't know), both interpretations
> above
> are legal. And you will find yourself in trouble.
>
> So do take the extra effort to write
>
> x = b*(*a);

Although this is clearer to you as a human reader, it is the exact same as
x = b**a

>
> just to make it indisputably clear what you mean. It might save you a
> bit of
> time later on. When I learned C, I did something like
>
> int i;
> float **a;
> float b;
>
> /* initialize *a to point to the start of an array of size N> i */
>
> b = *a[i];
>
> This one worked fine until Iported to a different system, where the
> whole program crashed. It took me weeks to find out about operator
> presdence and learn that the *a and a[i] operatoes were at the same
> level. One compiler implemented the expression as
>
> b = (*a)[i];
>
> which was what I wanted, the other implemented it as
>
> b = *(a[i]);
>
> which crashed.
>
> So, the devil is in the details!
>
> Rune
>
>
>>Thanks in
>>advance everyone,
>>
>>Eric Wendel
>>
>>The following code is contained inside my mexFunction.
>>[code]
>>#include "math.h"
>>#include "mdefs.h" /* Contains definitions of math expressions like
>>Sin(x) and Power(x) */
>>#include "mex.h"
>>... [snip]
>> double *guard, *x5, *x6, *x7;
>> double *x5dot, *x6dot, *x7dot, *x5dotnew, *x6dotnew, *x7dotnew;
>> double *x5dotdot, *x6dotdot, *x7dotdot;
>>... [snip]
>> x5 = mxCalloc(1, sizeof(long double));
>> x6 = mxCalloc(1, sizeof(long double));
>> x7 = mxCalloc(1, sizeof(long double));
>> x5dot = mxCalloc(1, sizeof(long double));
>> x6dot = mxCalloc(1, sizeof(long double));
>> x7dot = mxCalloc(1, sizeof(long double));
>> x5dotnew = mxCalloc(1, sizeof(long double));
>> x6dotnew = mxCalloc(1, sizeof(long double));
>> x7dotnew = mxCalloc(1, sizeof(long double));
>> x5dotdot = mxCalloc(1, sizeof(long double));
>> x6dotdot = mxCalloc(1, sizeof(long double));
>> x7dotdot = mxCalloc(1, sizeof(long double));
>> guard = mxCalloc(1, sizeof(long double));

Change declarations to long double or change memory allocation to double.

>>
>> *x5 = q_in[0];
>> *x6 = q_in[1];
>> *x7 = q_in[2];
>> *x5dot = q_in[3];
>> *x6dot = q_in[4];
>> *x7dot = q_in[5];
>>... [snip]
>> *x5dotdot = (2*(2*g*((3*M + 2*Mp)*Cos(*x6) - ... /* Several
>>more lines ... */
>> *x6dotdot = (4*l*M*(Power(*x6dot + *x7dot,2)*Sin(*x7) - ... /*
>>Several more lines ... */
>> *x7dotdot = (l*(4**x6dot**x7dot*M*(-1 + ... /* Several more
>>lines ... */
>> plhs[0] = mxCreateDoubleMatrix(dim, 1, mxREAL);
>> if (plhs[0] == NULL) dieHorribly(-1);
>> mxGetPr(plhs[0])[0] = *x5dot;
>> mxGetPr(plhs[0])[1] = *x6dot;
>> mxGetPr(plhs[0])[2] = *x7dot;
>> mxGetPr(plhs[0])[3] = *x5dotdot;
>> mxGetPr(plhs[0])[4] = *x6dotdot;
>> mxGetPr(plhs[0])[5] = *x7dotdot;
>>... [snip]
>> mxFree(x5);
>> mxFree(x6);
>> mxFree(x7);
>> mxFree(x5dot);
>> mxFree(x6dot);
>> mxFree(x7dot);
>> mxFree(x5dotnew);
>> mxFree(x6dotnew);
>> mxFree(x7dotnew);
>> mxFree(x5dotdot);
>> mxFree(x6dotdot);
>> mxFree(x7dotdot);
>> mxFree(guard);
>>[/code]
>>
>>Pseudocode:
>>1) Declare double pointers x5, x6, etc, and pass values of prhs into
>>these pointers after allocating 32-bit space for them (long double)
>>using mxCalloc.
>>2) Run *x5, *x6, etc through my complicated equations.
>>3) Tell Matlab matrix plhs[0] to point to the same memory addresses of
>>x5dot, x6dot, etc.
>>I know the error message pops up between 1) and 2).
>
>
.



Relevant Pages

  • Re: OT: Requesting C advice
    ... some behind the scenes action of the compiler. ... In fact the memory could ... Proper initialization means that floats and doubles must be initialized to 0.0 and pointers must be initialized to the null pointer value, even if those bit patterns differ from all-bits-zero. ...
    (Fedora)
  • Re: Is There Any Reason to Even Use VC++ Anymore?
    ... If, for another reason, the calling function needs to allocate memory, ... It does this by taking a pointer to a ball object ...
    (microsoft.public.dotnet.languages.vc)
  • Re: Pointer to the out of scope local variables
    ... of a pointer, and jumped to the conclusion that you allocated the memory ... In this particular case the funtion buildPoint would allocate ... If the caller ...
    (microsoft.public.vc.language)
  • Re: Mex Overflow Error Using Free Borland Compiler
    ... >>>Borland compiler handles overflow errors. ... >>>The first thing I tried is dynamic memory allocation. ... > 1- You declare the variables of type double and allocate of size long double. ... > would clean up a lot of code by eliminating the pointer dereferences. ...
    (comp.soft-sys.matlab)
  • Re: Memory management and allocation
    ... > As I'm writing a piece of code that basically acts as a server and ... > memory management is a topic that is quite crucial. ... Or can I just allocate the variable ... Nor is it usually necessary to set the pointer to ...
    (comp.lang.c)

Loading