Funny problem with virtual method

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Markus Svilans

    #1

    Funny problem with virtual method

    Hi,

    I have a weird problem in a virtual method. The original method code
    raises an access violation when it is run. The solution to the problem
    is to declare a dummy integer inside the virtual method. Then the
    access violation no longer occurs!

    The following class (condensed from the NetCDF C++ interface):

    class NcVar : public NcTypedComponen t
    {
    public:
    // This method implements an abstract method in NcTypedComponen t
    virtual NcType type() const;
    private:
    int dim_to_index(Nc Dim* rdim);
    int the_id;
    };

    Original implementation of type():

    NcType NcVar::type() const
    {
    // nc_inq_vartype is a library function that works normally
    // outside of this method
    nc_type typ;
    nc_inq_vartype( the_file->id(), the_id, &typ);
    return (NcType)typ;
    }

    Running this code raises an access violation. Calling the exact same
    code outside of the method works perfectly.

    Modified implementation of type():

    NcType NcVar::type() const
    {
    int x; // That's right, adding this makes it work

    nc_type typ = 0;
    nc_inq_vartype( the_file->id(), the_id, &typ);
    return (NcType)typ;
    }

    Adding the "int x" makes the code run, without any access violations!
    A few other of the virtual methods in other classes have a similar
    problem.

    What's going on here?

    FYI, this code is from the NetCDF C++ interface. I am trying to use it
    with Borland C++ Builder 6. I did not write the NetCDF C++ interface,
    but I am trying to use it as-is, and the access violation problem has
    been driving me nuts.

    Any help would be appreciated.

    Regards,
    Markus.

  • Ondra Holub

    #2
    Re: Funny problem with virtual method


    Markus Svilans napsal:
    Hi,
    >
    I have a weird problem in a virtual method. The original method code
    raises an access violation when it is run. The solution to the problem
    is to declare a dummy integer inside the virtual method. Then the
    access violation no longer occurs!
    >
    The following class (condensed from the NetCDF C++ interface):
    >
    class NcVar : public NcTypedComponen t
    {
    public:
    // This method implements an abstract method in NcTypedComponen t
    virtual NcType type() const;
    private:
    int dim_to_index(Nc Dim* rdim);
    int the_id;
    };
    >
    Original implementation of type():
    >
    NcType NcVar::type() const
    {
    // nc_inq_vartype is a library function that works normally
    // outside of this method
    nc_type typ;
    nc_inq_vartype( the_file->id(), the_id, &typ);
    return (NcType)typ;
    }
    >
    Running this code raises an access violation. Calling the exact same
    code outside of the method works perfectly.
    >
    Modified implementation of type():
    >
    NcType NcVar::type() const
    {
    int x; // That's right, adding this makes it work
    >
    nc_type typ = 0;
    nc_inq_vartype( the_file->id(), the_id, &typ);
    return (NcType)typ;
    }
    >
    Adding the "int x" makes the code run, without any access violations!
    A few other of the virtual methods in other classes have a similar
    problem.
    >
    What's going on here?
    >
    FYI, this code is from the NetCDF C++ interface. I am trying to use it
    with Borland C++ Builder 6. I did not write the NetCDF C++ interface,
    but I am trying to use it as-is, and the access violation problem has
    been driving me nuts.
    >
    Any help would be appreciated.
    >
    Regards,
    Markus.
    I think you are somewhere overwriting memory.

    Comment

    • Jim Langston

      #3
      Re: Funny problem with virtual method

      "Markus Svilans" <msvilans@gmail .comwrote in message
      news:1164399336 .569840.249330@ l39g2000cwd.goo glegroups.com.. .
      Hi,
      >
      I have a weird problem in a virtual method. The original method code
      raises an access violation when it is run. The solution to the problem
      is to declare a dummy integer inside the virtual method. Then the
      access violation no longer occurs!
      >
      The following class (condensed from the NetCDF C++ interface):
      >
      class NcVar : public NcTypedComponen t
      {
      public:
      // This method implements an abstract method in NcTypedComponen t
      virtual NcType type() const;
      private:
      int dim_to_index(Nc Dim* rdim);
      int the_id;
      };
      >
      Original implementation of type():
      >
      NcType NcVar::type() const
      {
      // nc_inq_vartype is a library function that works normally
      // outside of this method
      nc_type typ;
      nc_inq_vartype( the_file->id(), the_id, &typ);
      return (NcType)typ;
      }
      >
      Running this code raises an access violation. Calling the exact same
      code outside of the method works perfectly.
      >
      Modified implementation of type():
      >
      NcType NcVar::type() const
      {
      int x; // That's right, adding this makes it work
      >
      nc_type typ = 0;
      nc_inq_vartype( the_file->id(), the_id, &typ);
      return (NcType)typ;
      }
      >
      Adding the "int x" makes the code run, without any access violations!
      A few other of the virtual methods in other classes have a similar
      problem.
      >
      What's going on here?
      >
      FYI, this code is from the NetCDF C++ interface. I am trying to use it
      with Borland C++ Builder 6. I did not write the NetCDF C++ interface,
      but I am trying to use it as-is, and the access violation problem has
      been driving me nuts.
      >
      Any help would be appreciated.
      >
      Regards,
      Markus.
      This type of error, you get an access violatoin, but you do something
      totally unrelated and it goes away, means you have a buffer overflow
      somewhere. Adding that new variable shuffled the variables around a bit,
      and it just means you're overwriting a variable that isn't immediately
      causing an access violation, but your problem is still there.

      Show a complete compilable program that causes the problem. I'll bet that
      you won't even send it to this newsgroup, however, as the act of doing this
      will show you where the problem is. If not, send the code.


      Comment

      • BobR

        #4
        Re: Funny problem with virtual method


        Markus Svilans wrote in message
        <1164399336.569 840.249330@l39g 2000cwd.googleg roups.com>...
        >Hi,
        >I have a weird problem in a virtual method. The original method code
        >raises an access violation when it is run. The solution to the problem
        >is to declare a dummy integer inside the virtual method. Then the
        >access violation no longer occurs!
        >The following class (condensed from the NetCDF C++ interface):
        >
        >class NcVar : public NcTypedComponen t { public:
        // This method implements an abstract method in NcTypedComponen t
        virtual NcType type() const;
        private:
        int dim_to_index( NcDim* rdim );
        int the_id;
        };
        >
        >Original implementation of type():
        >
        >NcType NcVar::type() const {
        // nc_inq_vartype is a library function that works normally
        // outside of this method
        nc_type typ;
        What is 'nc_type'?
        nc_inq_vartype( the_file->id(), the_id, &typ );
        What is 'the_file' pointing to?


        // return (NcType)typ;

        What is 'NcType'?

        Pick one (try all).
        return NcType( typ );
        return static_cast<NcT ype>( typ );
        return dynamic_cast<Nc Type>( typ );
        return reinterpret_cas t<NcType>( typ );

        Remove the cast and see what your compiler is trying to do!
        The 'C' cast may be covering up an error.

        return typ;
        >}
        >
        >Running this code raises an access violation. Calling the exact same
        >code outside of the method works perfectly.
        Show the call that works.

        --
        Bob R
        POVrookie


        Comment

        • Markus Svilans

          #5
          Re: Funny problem with virtual method


          Jim Langston wrote:
          >
          This type of error, you get an access violatoin, but you do something
          totally unrelated and it goes away, means you have a buffer overflow
          somewhere. Adding that new variable shuffled the variables around a bit,
          and it just means you're overwriting a variable that isn't immediately
          causing an access violation, but your problem is still there.
          >
          Show a complete compilable program that causes the problem. I'll bet that
          you won't even send it to this newsgroup, however, as the act of doing this
          will show you where the problem is. If not, send the code.
          Hi Jim,

          Thanks for the reply. I'll put together a compilable program that
          should demonstrate the problem, assuming you have the NetCDF library
          installed (http://www.unidata.ucar.edu/software/netcdf/).

          The funny thing is, that access violation pops up when I try to compile
          and run one of the demo programs that comes with the library.

          Regards,
          Markus.

          Comment

          • Tim D

            #6
            Re: Funny problem with virtual method

            Markus Svilans wrote:
            Hi,
            >
            I have a weird problem in a virtual method. The original method code
            raises an access violation when it is run. The solution to the problem
            is to declare a dummy integer inside the virtual method. Then the
            access violation no longer occurs!
            >
            The following class (condensed from the NetCDF C++ interface):
            >
            class NcVar : public NcTypedComponen t
            {
            public:
            // This method implements an abstract method in NcTypedComponen t
            virtual NcType type() const;
            private:
            int dim_to_index(Nc Dim* rdim);
            int the_id;
            };
            >
            Original implementation of type():
            >
            NcType NcVar::type() const
            {
            // nc_inq_vartype is a library function that works normally
            // outside of this method
            nc_type typ;
            nc_inq_vartype( the_file->id(), the_id, &typ);
            return (NcType)typ;
            }
            >
            Running this code raises an access violation. Calling the exact same
            code outside of the method works perfectly.
            >
            Modified implementation of type():
            >
            NcType NcVar::type() const
            {
            int x; // That's right, adding this makes it work
            >
            nc_type typ = 0;
            nc_inq_vartype( the_file->id(), the_id, &typ);
            return (NcType)typ;
            }
            >
            Adding the "int x" makes the code run, without any access violations!
            A few other of the virtual methods in other classes have a similar
            problem.
            >
            What's going on here?
            >
            FYI, this code is from the NetCDF C++ interface. I am trying to use it
            with Borland C++ Builder 6. I did not write the NetCDF C++ interface,
            but I am trying to use it as-is, and the access violation problem has
            been driving me nuts.
            >
            Any help would be appreciated.
            >
            Regards,
            Markus.
            when you "return (NcType)type;" you are copying the NcType object back to
            the caller. NcType is an object, I don't know what nc_type is, but it could
            be that Borland is just being way too liberal in its type casting. Try
            getting rid of the "int x;" and replace the return with:

            NcType ncType(nc_type) ; // or however one usually converts an nc_type to
            NcType
            return ncType;

            If the problem goes away, it means that NcType is bigger than nc_type and
            you tried to copy junk outside of your stack frame.

            Comment

            • Markus Svilans

              #7
              Re: Funny problem with virtual method


              Jim Langston wrote:
              This type of error, you get an access violatoin, but you do something
              totally unrelated and it goes away, means you have a buffer overflow
              somewhere. Adding that new variable shuffled the variables around a bit,
              and it just means you're overwriting a variable that isn't immediately
              causing an access violation, but your problem is still there.
              >
              Show a complete compilable program that causes the problem. I'll bet that
              you won't even send it to this newsgroup, however, as the act of doing this
              will show you where the problem is. If not, send the code.
              Hi Jim,

              The program I am trying to run is here:


              I am using Borland C++ Builder 6 Personal, with the Windows DLL version
              of the netCDF 3.6.1 library. In order to compile the program, you will
              have to install the netCDF library somehow.

              I am assuming that my problem lies somewhere with the C++ interface to
              the library, and not the library itself, because I can use the C
              function calls without any access violations.

              If you would like me to send you a copy of the C++ interface of the
              library, please let me know.

              Regards,
              Markus.

              Comment

              • Markus Svilans

                #8
                Re: Funny problem with virtual method


                BobR wrote:
                NcType NcVar::type() const {
                // nc_inq_vartype is a library function that works normally
                // outside of this method
                nc_type typ;
                >
                What is 'nc_type'?
                nc_type is an enumerated type.
                nc_inq_vartype( the_file->id(), the_id, &typ );
                >
                What is 'the_file' pointing to?
                the_file is an NcFile object, and the id() method just returns an
                integer representing the unique identifier of the NcFile object.

                the_id is another integer (a member of the NcVar class) that is passed
                to nc_inq_vartype( ).
                // return (NcType)typ;
                >
                What is 'NcType'?
                NcType is an enumerated type, that mirrors the nc_type enumerator
                member by member. (This is why directly casting from one to another
                works.)
                Pick one (try all).
                return NcType( typ );
                return static_cast<NcT ype>( typ );
                return dynamic_cast<Nc Type>( typ );
                return reinterpret_cas t<NcType>( typ );
                I tried all of these, and those that compiled did not aleviate the
                problem...

                Regards,
                Markus.

                Comment

                • Markus Svilans

                  #9
                  Re: Funny problem with virtual method


                  Tim D wrote:
                  when you "return (NcType)type;" you are copying the NcType object back to
                  the caller. NcType is an object, I don't know what nc_type is, but it could
                  be that Borland is just being way too liberal in its type casting. Try
                  getting rid of the "int x;" and replace the return with:
                  >
                  NcType ncType(nc_type) ; // or however one usually converts an nc_type to
                  NcType
                  return ncType;
                  >
                  If the problem goes away, it means that NcType is bigger than nc_type and
                  you tried to copy junk outside of your stack frame.

                  NcType and nc_type are both enumerators, whose members have a 1:1
                  correspondence to each other. In effect NcType is an alias for nc_type.
                  The two types exist because the nc_type enumerator is used in the pure
                  C library function calls, and NcType is used for the C++ interface.

                  Regards,
                  Markus.

                  Comment

                  • BobR

                    #10
                    Re: Funny problem with virtual method


                    Markus Svilans wrote in message ...
                    >
                    >BobR wrote:
                    >
                    >Pick one (try all).
                    > return NcType( typ );
                    > return static_cast<NcT ype>( typ );
                    > return dynamic_cast<Nc Type>( typ );
                    > return reinterpret_cas t<NcType>( typ );
                    >
                    >I tried all of these, and those that compiled did not aleviate the
                    >problem...
                    Well, duh. It wasn't meant to 'aleviate the problem', but, to show what type
                    the function was returning and what was expected. ( I should have explicitely
                    asked you to post the errors on each.). But, if you have to cast, use one of
                    those (probably 'static_cast').

                    So, what is the error on:
                    return typ;

                    ( remove the line number and pathname, just post the error part.)

                    --
                    Bob R
                    POVrookie


                    Comment

                    • Markus Svilans

                      #11
                      Re: Funny problem with virtual method


                      BobR wrote:
                      Markus Svilans wrote in message ...

                      BobR wrote:
                      Pick one (try all).
                      return NcType( typ );
                      return static_cast<NcT ype>( typ );
                      return dynamic_cast<Nc Type>( typ );
                      return reinterpret_cas t<NcType>( typ );
                      I tried all of these, and those that compiled did not aleviate the
                      problem...
                      >
                      Well, duh. It wasn't meant to 'aleviate the problem', but, to show what type
                      the function was returning and what was expected. ( I should have explicitely
                      asked you to post the errors on each.). But, if you have to cast, use one of
                      those (probably 'static_cast').
                      >
                      So, what is the error on:
                      return typ;
                      >
                      ( remove the line number and pathname, just post the error part.)

                      The warning message for "return typ" was:

                      W8006 Initializing NcType with nc_type

                      As I said, NcType and nc_type are both enumerators.

                      Thanks,
                      Markus.

                      Comment

                      Working...