class initialization problem, please help

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

    class initialization problem, please help

    hi, there
    Here is a simplified piece of code of my program, it compiles and runs
    fine. However, valgrind shows it has uninitialized problem. What I am
    doing wrong?

    #ifndef DATA2_H
    #define DATA2_H

    class Data2{
    public:
    int regionId;
    bool isLandscape;
    double parameters[16];
    Data2();

    ~Data2();
    };
    #endif

    #include "data2.h"
    #include <iomanip>
    #include <fstream>

    using namespace std;

    Data2::Data2(): regionId(-1), isLandscape(fal se)
    {
    for (int i = 0; i < 16; i++)
    parameters[i] = 1;
    }

    Data2::~Data2()
    {
    }

    int main(){
    char buffer[512] = "abc.bin";
    ofstream myfile;
    Data2 *dataArray = new Data2[10];

    myfile.open (buffer, ios::out | ios::binary);
    int *num = new int(10);
    myfile.write((c har*)num, sizeof(int));
    myfile.write ((char*)dataArr ay, sizeof (Data2) * *num);
    myfile.close();
    delete num;
    delete [] dataArray;
    return 1;
    }

    valgrind error message:
    ==16557== 1 errors in context 1 of 1:
    ==16557== Syscall param writev(vector[...]) points to uninitialised
    byte(s)
    ==16557== at 0x40007F2: (within /lib/ld-2.7.so)
    ==16557== by 0x5A70707: std::__basic_fi le<char>::xsput n_2(char
    const*, int, char const*, int) (in /usr/lib/libstdc++.so.6. 0.9)
    ==16557== by 0x5A171E9: std::basic_file buf<char,
    std::char_trait s<char::xsputn( char const*, int) (in /usr/lib/libstdc
    ++.so.6.0.9)
    ==16557== by 0x5A42DE0: std::ostream::w rite(char const*, int) (in /
    usr/lib/libstdc++.so.6. 0.9)
    ==16557== by 0x81535AD: main (data2.cpp:36)
    ==16557== Address 0x61540b9 is 9 bytes inside a block of size 1,364
    alloc'd
    ==16557== at 0x4022F14: operator new[](unsigned)
    (vg_replace_mal loc.c:268)
    ==16557== by 0x81534AE: main (data2.cpp:31)
    --16557--
    --16557-- supp: 131 dl-hack3-1
    ==16557==
    ==16557== IN SUMMARY: 1 errors from 1 contexts (suppressed: 131 from
    1)
    ==16557==
    ==16557== malloc/free: in use at exit: 528 bytes in 10 blocks.
    ==16557== malloc/free: 534 allocs, 524 frees, 49,265 bytes allocated.
    ==16557==
    ==16557== searching for pointers to 10 not-freed blocks.
    ==16557== checked 1,449,340 bytes.
    ==16557==
    ==16557== LEAK SUMMARY:
    ==16557== definitely lost: 0 bytes in 0 blocks.
    ==16557== possibly lost: 0 bytes in 0 blocks.
    ==16557== still reachable: 528 bytes in 10 blocks.
    ==16557== suppressed: 0 bytes in 0 blocks.

    Thanks for your comments.

    zl2k
  • Triple-DES

    #2
    Re: class initialization problem, please help

    On 26 Sep, 05:04, zl2k <kdsfin...@gmai l.comwrote:
    hi, there
    Here is a simplified piece of code of my program, it compiles and runs
    fine. However, valgrind shows it has uninitialized problem. What I am
    doing wrong?
    >
    #ifndef DATA2_H
    #define DATA2_H
    >
    class Data2{
    public:
            int regionId;
            bool isLandscape;
            double parameters[16];
      Data2();
    >
      ~Data2();};
    >
    #endif
    >
    #include "data2.h"
    #include <iomanip>
    #include <fstream>
    >
    using namespace std;
    >
    Data2::Data2(): regionId(-1), isLandscape(fal se)
    {
            for (int i = 0; i < 16; i++)
                    parameters[i] = 1;
    >
    }
    >
    Data2::~Data2()
    {
    >
    }
    >
    int main(){
            char buffer[512] = "abc.bin";
            ofstream myfile;
            Data2 *dataArray = new Data2[10];
    >
            myfile.open (buffer, ios::out | ios::binary);
            int *num = new int(10);
            myfile.write((c har*)num, sizeof(int));
            myfile.write ((char*)dataArr ay, sizeof (Data2) * *num);
            myfile.close();
            delete num;
            delete [] dataArray;
            return 1;
    >
    }
    >
    Try the following:
    int data2size = sizeof(Data2);
    int membersize = sizeof(int) + sizeof(bool) + sizeof(double)* 16;

    What are these values on your system?
    Does that tell you anything ? :)

    DP

    Comment

    • James Kanze

      #3
      Re: class initialization problem, please help

      On Sep 26, 5:04 am, zl2k <kdsfin...@gmai l.comwrote:
      Here is a simplified piece of code of my program, it compiles
      and runs fine. However, valgrind shows it has uninitialized
      problem. What I am doing wrong?
      You're misusing reinterpret_cas t.
      #ifndef DATA2_H
      #define DATA2_H
      class Data2{
      public:
      int regionId;
      bool isLandscape;
      double parameters[16];
      Data2();
      ~Data2();
      };
      #endif
      #include "data2.h"
      #include <iomanip>
      #include <fstream>
      using namespace std;
      Data2::Data2(): regionId(-1), isLandscape(fal se)
      {
      for (int i = 0; i < 16; i++)
      parameters[i] = 1;
      }
      Data2::~Data2()
      {
      }
      int main(){
      char buffer[512] = "abc.bin";
      ofstream myfile;
      Data2 *dataArray = new Data2[10];
      myfile.open (buffer, ios::out | ios::binary);
      int *num = new int(10);
      myfile.write((c har*)num, sizeof(int));
      myfile.write ((char*)dataArr ay, sizeof (Data2) * *num);
      The casts in the two statements above are reinterpret_cas t's;
      you shouldn't be using them unless you really know what you are
      doing. And you shouldn't be too surprised that valgrind finds
      errors if you do use them.

      In this particular case, the standard does guarantee that the
      write's will work, despite the uninitialized memory reads, but
      only because ofstream is guaranteed to access the data as bytes.
      On the other hand, it doesn't say anything about what will
      actually be written, and it doesn't guarantee that you will be
      able to reread it---in practice, you may encounter problems
      rereading it if you recompile the program with different
      compiler options, or with a newer version of the compiler, and
      you will almost certainly encouter problems trying to reread it
      if you run the program on another machine.

      Dumping bit images to disk doesn't work, except for temporary
      files that you will reread later in the same program run.

      --
      James Kanze (GABI Software) email:james.kan ze@gmail.com
      Conseils en informatique orientée objet/
      Beratung in objektorientier ter Datenverarbeitu ng
      9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

      Comment

      • zl2k

        #4
        Re: class initialization problem, please help

        On Sep 26, 2:17 am, Triple-DES <DenPlettf...@g mail.comwrote:
        On 26 Sep, 05:04, zl2k <kdsfin...@gmai l.comwrote:
        >
        >
        >
        hi, there
        Here is a simplified piece of code of my program, it compiles and runs
        fine. However, valgrind shows it has uninitialized problem. What I am
        doing wrong?
        >
        #ifndef DATA2_H
        #define DATA2_H
        >
        class Data2{
        public:
                int regionId;
                bool isLandscape;
                double parameters[16];
          Data2();
        >
          ~Data2();};
        >
        #endif
        >
        #include "data2.h"
        #include <iomanip>
        #include <fstream>
        >
        using namespace std;
        >
        Data2::Data2(): regionId(-1), isLandscape(fal se)
        {
                for (int i = 0; i < 16; i++)
                        parameters[i] = 1;
        >
        }
        >
        Data2::~Data2()
        {
        >
        }
        >
        int main(){
                char buffer[512] = "abc.bin";
                ofstream myfile;
                Data2 *dataArray = new Data2[10];
        >
                myfile.open (buffer, ios::out | ios::binary);
                int *num = new int(10);
                myfile.write((c har*)num, sizeof(int));
                myfile.write ((char*)dataArr ay, sizeof (Data2) * *num);
                myfile.close();
                delete num;
                delete [] dataArray;
                return 1;
        >
        }
        >
        Try the following:
          int data2size = sizeof(Data2);
          int membersize = sizeof(int) + sizeof(bool) + sizeof(double)* 16;
        >
        What are these values on your system?
        Does that tell you anything ? :)
        >
        DP
        It's different! To make it simpler, the Data2 will only contains an
        int and a bool, the data2size is 8 and membersize is 5. I am fine if
        using 5 for output. The sizeof(ClassTyp e) is bad, is it? Thanks a lot.
        zl2k

        Comment

        • Triple-DES

          #5
          Re: class initialization problem, please help

          On 26 Sep, 13:37, zl2k <kdsfin...@gmai l.comwrote:
          On Sep 26, 2:17 am, Triple-DES <DenPlettf...@g mail.comwrote:
          On 26 Sep, 05:04, zl2k <kdsfin...@gmai l.comwrote:
          >
          hi, there
          Here is a simplified piece of code of my program, it compiles and runs
          fine. However, valgrind shows it has uninitialized problem. What I am
          doing wrong?
          >
          #ifndef DATA2_H
          #define DATA2_H
          >
          class Data2{
          public:
                  int regionId;
                  bool isLandscape;
                  double parameters[16];
            Data2();
          >
            ~Data2();};
          >
          #endif
          >
          #include "data2.h"
          #include <iomanip>
          #include <fstream>
          >
          using namespace std;
          >
          Data2::Data2(): regionId(-1), isLandscape(fal se)
          {
                  for (int i = 0; i < 16; i++)
                          parameters[i] = 1;
          >
          }
          >
          Data2::~Data2()
          {
          >
          }
          >
          int main(){
                  char buffer[512] = "abc.bin";
                  ofstream myfile;
                  Data2 *dataArray = new Data2[10];
          >
                  myfile.open (buffer, ios::out | ios::binary);
                  int *num = new int(10);
                  myfile.write((c har*)num, sizeof(int));
                  myfile.write ((char*)dataArr ay, sizeof (Data2) * *num);
                  myfile.close();
                  delete num;
                  delete [] dataArray;
                  return 1;
          >
          }
          >
          Try the following:
            int data2size = sizeof(Data2);
            int membersize = sizeof(int) + sizeof(bool) + sizeof(double)* 16;
          >
          What are these values on your system?
          Does that tell you anything ? :)
          >
          DP
          >
          It's different! To make it simpler, the Data2 will only contains an
          int and a bool, the data2size is 8 and membersize is 5. I am fine if
          using 5 for output. The sizeof(ClassTyp e) is bad, is it? Thanks a lot.
          zl2k
          You're onto something, but your conclusion is wrong I think. What I
          wanted to show you was that the Data2 class may very well be larger
          than the sum of its members (sizeof returns the number of bytes of the
          object). So what are those extra bytes?

          Put simply, they are "padding" inserted by the compiler so that it may
          access the members of the class more efficiently. This is commonly
          referred to as _alignment_. Naturally when you take the address of the
          object and interpret it as a char*, you will expose the padding bytes.

          Data2 possible object layout:
          [ 0 ][ 1 ][ 2 ][ 3 ][ 4 ][ 5 ][ 6 ][ 7 ]
          [ int (4 bytes) ][bool][ padding ]

          The padding could be set to a special value by the compiler to
          correspond to "uninitiali zed memory", or it could simply be garbage.
          Hence, your binary file will have bytes with an unspecified value
          written to it.

          Class member alignment may vary depending on architecture and compiler
          version, and even the settings of the compiler. This is covered by
          James Kanze's post.

          DP

          Comment

          • zl2k

            #6
            Re: class initialization problem, please help

            On Sep 26, 8:23 am, Triple-DES <DenPlettf...@g mail.comwrote:
            On 26 Sep, 13:37, zl2k <kdsfin...@gmai l.comwrote:
            >
            >
            >
            On Sep 26, 2:17 am, Triple-DES <DenPlettf...@g mail.comwrote:
            On 26 Sep, 05:04, zl2k <kdsfin...@gmai l.comwrote:
            >
            hi, there
            Here is a simplified piece of code of my program, it compiles and runs
            fine. However, valgrind shows it has uninitialized problem. What I am
            doing wrong?
            >
            #ifndef DATA2_H
            #define DATA2_H
            >
            class Data2{
            public:
                    int regionId;
                    bool isLandscape;
                    double parameters[16];
              Data2();
            >
              ~Data2();};
            >
            #endif
            >
            #include "data2.h"
            #include <iomanip>
            #include <fstream>
            >
            using namespace std;
            >
            Data2::Data2(): regionId(-1), isLandscape(fal se)
            {
                    for (int i = 0; i < 16; i++)
                            parameters[i] = 1;
            >
            }
            >
            Data2::~Data2()
            {
            >
            }
            >
            int main(){
                    char buffer[512] = "abc.bin";
                    ofstream myfile;
                    Data2 *dataArray = new Data2[10];
            >
                    myfile.open (buffer, ios::out | ios::binary);
                    int *num = new int(10);
                    myfile.write((c har*)num, sizeof(int));
                    myfile.write ((char*)dataArr ay, sizeof (Data2) * *num);
                    myfile.close();
                    delete num;
                    delete [] dataArray;
                    return 1;
            >
            }
            >
            Try the following:
              int data2size = sizeof(Data2);
              int membersize = sizeof(int) + sizeof(bool) + sizeof(double)* 16;
            >
            What are these values on your system?
            Does that tell you anything ? :)
            >
            DP
            >
            It's different! To make it simpler, the Data2 will only contains an
            int and a bool, the data2size is 8 and membersize is 5. I am fine if
            using 5 for output. The sizeof(ClassTyp e) is bad, is it? Thanks a lot.
            zl2k
            >
            You're onto something, but your conclusion is wrong I think. What I
            wanted to show you was that the Data2 class may very well be larger
            than the sum of its members (sizeof returns the number of bytes of the
            object). So what are those extra bytes?
            >
            Put simply, they are "padding" inserted by the compiler so that it may
            access the members of the class more efficiently. This is commonly
            referred to as _alignment_. Naturally when you take the address of the
            object and interpret it as a char*, you will expose the padding bytes.
            >
            Data2 possible object layout:
            [ 0 ][ 1 ][ 2 ][ 3 ][ 4 ][ 5 ][ 6 ][ 7 ]
            [  int (4 bytes)   ][bool][  padding   ]
            >
            The padding could be set to a special value by the compiler to
            correspond to "uninitiali zed memory", or it could simply be garbage.
            Hence, your binary file will have bytes with an unspecified value
            written to it.
            >
            Class member alignment may vary depending on architecture and compiler
            version, and even the settings of the compiler. This is covered by
            James Kanze's post.
            >
            DP
            So both implements are correct and the valgrind is false alarming,
            right? Basically, as long as my reading of the file using the same
            sizeof() as the writting, I'll be fine. But I am still facing risk if
            the file is going to be read by other systems later on if using
            sizeof(ClassTyp e). The conclusion is draw is telling the system the
            exact length of the ClassType "manually". Hope I get it right. Thanks
            again and this forum helps me a lot.
            zl2k

            Comment

            • Triple-DES

              #7
              Re: class initialization problem, please help

              On 26 Sep, 14:40, zl2k <kdsfin...@gmai l.comwrote:
              On Sep 26, 8:23 am, Triple-DES <DenPlettf...@g mail.comwrote:
              On 26 Sep, 13:37, zl2k <kdsfin...@gmai l.comwrote:
              On Sep 26, 2:17 am, Triple-DES <DenPlettf...@g mail.comwrote:
              On 26 Sep, 05:04, zl2k <kdsfin...@gmai l.comwrote:
              hi, there
              Here is a simplified piece of code of my program, it compiles andruns
              fine. However, valgrind shows it has uninitialized problem. What I am
              doing wrong?
              [snip]
              Try the following:
                int data2size = sizeof(Data2);
                int membersize = sizeof(int) + sizeof(bool) + sizeof(double)* 16;
              >
              What are these values on your system?
              Does that tell you anything ? :)
              >
              DP
              >
              It's different! To make it simpler, the Data2 will only contains an
              int and a bool, the data2size is 8 and membersize is 5. I am fine if
              using 5 for output. The sizeof(ClassTyp e) is bad, is it? Thanks a lot..
              zl2k
              >
              You're onto something, but your conclusion is wrong I think. What I
              wanted to show you was that the Data2 class may very well be larger
              than the sum of its members (sizeof returns the number of bytes of the
              object). So what are those extra bytes?
              >
              Put simply, they are "padding" inserted by the compiler so that it may
              access the members of the class more efficiently. This is commonly
              referred to as _alignment_. Naturally when you take the address of the
              object and interpret it as a char*, you will expose the padding bytes.
              >
              Data2 possible object layout:
              [ 0 ][ 1 ][ 2 ][ 3 ][ 4 ][ 5 ][ 6 ][ 7 ]
              [  int (4 bytes)   ][bool][  padding   ]
              >
              The padding could be set to a special value by the compiler to
              correspond to "uninitiali zed memory", or it could simply be garbage.
              Hence, your binary file will have bytes with an unspecified value
              written to it.
              >
              Class member alignment may vary depending on architecture and compiler
              version, and even the settings of the compiler. This is covered by
              James Kanze's post.
              >
              DP
              >
              So both implements are correct and the valgrind is false alarming,
              right? Basically, as long as my reading of the file using the same
              sizeof() as the writting, I'll be fine. But I am still facing risk if
              the file is going to be read by other systems later on if using
              sizeof(ClassTyp e). The conclusion is draw is telling the system the
              exact length of the ClassType "manually". Hope I get it right. Thanks
              again and this forum helps me a lot.
              zl2k
              Not quite. Manually calculating the size of the members won't help if
              there is padding _between_ the members. Note also that valgrind is not
              really giving a false alarm since the padding bytes are in fact
              uninitialized.

              DP

              Comment

              • James Kanze

                #8
                Re: class initialization problem, please help

                On Sep 26, 2:23 pm, Triple-DES <DenPlettf...@g mail.comwrote:
                On 26 Sep, 13:37, zl2k <kdsfin...@gmai l.comwrote:
                [...]
                Class member alignment may vary depending on architecture and
                compiler version, and even the settings of the compiler. This
                is covered by James Kanze's post.
                Except that I explicitly avoided talking about padding (although
                I'm sure that that's the immediate problem), since there's a lot
                more to it than just padding. The representation of basic types
                varies a lot, and at least in one case, it changed from one
                version of the compiler to the next. If you want your data to
                be readable in the future, you have to define a format, and use
                it.

                --
                James Kanze (GABI Software) email:james.kan ze@gmail.com
                Conseils en informatique orientée objet/
                Beratung in objektorientier ter Datenverarbeitu ng
                9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                Comment

                • zl2k

                  #9
                  Re: class initialization problem, please help

                  On Sep 26, 9:02 am, Triple-DES <DenPlettf...@g mail.comwrote:
                  On 26 Sep, 14:40, zl2k <kdsfin...@gmai l.comwrote:
                  >
                  On Sep 26, 8:23 am, Triple-DES <DenPlettf...@g mail.comwrote:
                  On 26 Sep, 13:37, zl2k <kdsfin...@gmai l.comwrote:
                  On Sep 26, 2:17 am, Triple-DES <DenPlettf...@g mail.comwrote:
                  On 26 Sep, 05:04, zl2k <kdsfin...@gmai l.comwrote:
                  hi, there
                  Here is a simplified piece of code of my program, it compiles and runs
                  fine. However, valgrind shows it has uninitialized problem. What I am
                  doing wrong?
                  >
                  [snip]
                  >
                  >
                  >
                  Try the following:
                    int data2size = sizeof(Data2);
                    int membersize = sizeof(int) + sizeof(bool) + sizeof(double)* 16;
                  >
                  What are these values on your system?
                  Does that tell you anything ? :)
                  >
                  DP
                  >
                  It's different! To make it simpler, the Data2 will only contains an
                  int and a bool, the data2size is 8 and membersize is 5. I am fine if
                  using 5 for output. The sizeof(ClassTyp e) is bad, is it? Thanks a lot.
                  zl2k
                  >
                  You're onto something, but your conclusion is wrong I think. What I
                  wanted to show you was that the Data2 class may very well be larger
                  than the sum of its members (sizeof returns the number of bytes of the
                  object). So what are those extra bytes?
                  >
                  Put simply, they are "padding" inserted by the compiler so that it may
                  access the members of the class more efficiently. This is commonly
                  referred to as _alignment_. Naturally when you take the address of the
                  object and interpret it as a char*, you will expose the padding bytes..
                  >
                  Data2 possible object layout:
                  [ 0 ][ 1 ][ 2 ][ 3 ][ 4 ][ 5 ][ 6 ][ 7 ]
                  [  int (4 bytes)   ][bool][  padding   ]
                  >
                  The padding could be set to a special value by the compiler to
                  correspond to "uninitiali zed memory", or it could simply be garbage.
                  Hence, your binary file will have bytes with an unspecified value
                  written to it.
                  >
                  Class member alignment may vary depending on architecture and compiler
                  version, and even the settings of the compiler. This is covered by
                  James Kanze's post.
                  >
                  DP
                  >
                  So both implements are correct and the valgrind is false alarming,
                  right? Basically, as long as my reading of the file using the same
                  sizeof() as the writting, I'll be fine. But I am still facing risk if
                  the file is going to be read by other systems later on if using
                  sizeof(ClassTyp e). The conclusion is draw is telling the system the
                  exact length of the ClassType "manually". Hope I get it right. Thanks
                  again and this forum helps me a lot.
                  zl2k
                  >
                  Not quite. Manually calculating the size of the members won't help if
                  there is padding _between_ the members. Note also that valgrind is not
                  really giving a false alarm since the padding bytes are in fact
                  uninitialized.
                  >
                  DP
                  The valgrind does give error message when I put the double[] back even
                  I "manually" tell the length of the ClassType. I can write each
                  element sequentially and manually for the ClassType, is that what I am
                  expected to do? It doesn't look like a smart way. Is there a standard
                  way to output the structure to the binary file? The c++ document of
                  microsoft uses myfile.write((c har*) classPointer,
                  sizeof(ClassTyp e)*LengthOfArra y). But I am using gun c++ in linux.
                  What is the correct way to do this safe that the output file can be
                  correctly read in any system? I am confused again.
                  zl2k

                  Comment

                  Working...