help-octave
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Antwort: Re: iterator problem in oct-file


From: John W. Eaton
Subject: Antwort: Re: iterator problem in oct-file
Date: Wed, 5 Jul 2006 03:18:31 -0400

On  5-Jul-2006, address@hidden wrote:

| ok, to make sure the same compiler was used for compiling octave and 
| compiling my .oct file, I reinstalled octave from the sources.
| The used compiler was g++ 4.0.4. The problem still occurs.  I hope the 
| attached bug report enables someone to track down the problem.

OK, I had another look at your original code:

  #include <string>
  #include <octave/oct.h> 
  #include <octave/ov-struct.h> 

  DEFUN_DLD (conversionExample, prhs, nlhs , 
   "Reproduces an Error which does not occur when cygwin is used")
  {
     double a;
     int b;
     std::string c;
     octave_value tmp;
     Octave_map::iterator p1;

        if ( !prhs(0).is_map() )
          {
            error("First input argument must be of type struct.");
            return octave_value(0);
          }

     p1 = prhs(0).map_value().seek("a");
     tmp =  prhs(0).map_value().contents(p1)(1);
     a = tmp.double_value();
     octave_stdout << "a is " << a << std::endl;

     p1 = prhs(0).map_value().seek("b");
     tmp =  prhs(0).map_value().contents(p1)(2);
     b = tmp.int_value();
     octave_stdout << "b is " << b << std::endl;

     p1 = prhs(0).map_value().seek("c");
     tmp =  prhs(0).map_value().contents(p1)(2);
     c = tmp.string_value().data();
     octave_stdout << "c is " << c << std::endl;
     return octave_value(0);

  }

I think you are depending on temporaries existing longer than they are
required to.

What happens if you try this instead:

  #include <string>
  #include <octave/oct.h> 
  #include <octave/ov-struct.h> 

  DEFUN_DLD (conversionExample, prhs, nlhs , 
   "Reproduces an Error which does not occur when cygwin is used")
  {
     double a;
     int b;
     std::string c;
     octave_value tmp;
     Octave_map::iterator p1;

        if ( !prhs(0).is_map() )
          {
            error("First input argument must be of type struct.");
            return octave_value(0);
          }

     Octave_map m = prhs(0).map_value();

     p1 = m.seek("a");
     tmp =  m.contents(p1)(1);
     a = tmp.double_value();
     octave_stdout << "a is " << a << std::endl;

     p1 = m.seek("b");
     tmp =  m.contents(p1)(2);
     b = tmp.int_value();
     octave_stdout << "b is " << b << std::endl;

     p1 = m.seek("c");
     tmp =  m.contents(p1)(2);
     c = tmp.string_value().data();
     octave_stdout << "c is " << c << std::endl;
     return octave_value(0);

  }

BTW, here is how I would write this function to check more carefully
for invalid input (and avoid crashing Octave if the input is not what
is expected):

  #include <octave/oct.h> 
  #include <octave/oct-map.h>

  DEFUN_DLD (conversionExample, args, ,
    "Reproduces an Error which does not occur when cygwin is used")
  {
    octave_value retval;

    if (args.length () > 0)
      {
        const Octave_map m = args(0).map_value ();

        if (! error_state)
          {
            // Might also check dimensions more carefully here...
            int numel = m.numel ();

            if (numel == 3)
              {
                Cell tmp;

                tmp = m.contents ("a");

                if (! tmp.is_empty ())
                  {
                    double a = tmp(1).double_value ();

                    if (! error_state)
                      octave_stdout << "a is " << a << std::endl;
                  }
                else
                  error ("struct field A not found");

                tmp = m.contents ("b");

                if (! tmp.is_empty ())
                  {
                    int b = tmp(2).int_value ();

                    if (! error_state)
                      octave_stdout << "b is " << b << std::endl;
                  }
                else
                  error ("struct field B not found");

                tmp = m.contents ("c");

                if (! tmp.is_empty ())
                  {
                    std::string c = tmp(2).string_value ();

                    if (! error_state)
                      octave_stdout << "c is " << c << std::endl;
                  }
                else
                  error ("struct field C not found");
              }
            else
              error ("expecting 3-element struct array");
          }
        else
          error ("expecting argument to be a struct");
      }
    else
      error ("expecting one argument");

    return retval;
  }

jwe


reply via email to

[Prev in Thread] Current Thread [Next in Thread]