Casting struct to char array (was: Linked List problem)

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

    #1

    Casting struct to char array (was: Linked List problem)


    "Richard Bos" <rlb@hoekstra-uitgeverij.nl> wrote in message news:4180f756.1 97032434@news.i ndividual.net.. . to news:comp.lang. c[color=blue]
    > ben19777@hotmai l.com (Ben) wrote:[/color]
    [snip][color=blue][color=green]
    > > 2) Structure casted into an array of char
    > > typedef struct {
    > > char name[20];
    > > int age;
    > > int id;
    > > } person;
    > >
    > > person p = (person *) malloc(sizeof(p erson));
    > > p.name="hello";
    > > p.age=2;
    > > p.id=2;
    > >
    > > char *a;
    > > a=(char *)p;[/color]
    >
    > No. You cannot cast a struct into a pointer. And what would you do this
    > for, anyway? Do you suppose that the bytes represented by "hello"
    > somehow form a valid pointer?
    > I suspect you meant to access the struct itself _through_, not _as_, a
    > pointer to char. In that case, you need to do
    >
    > a = (char *)&p;
    >
    > which is perfectly legal, and can be useful - though rarely. Beware the
    > padding bytes!
    >[/color]
    [snip]

    Is it possible to write 'operator char*()' inside the C++-structure that enables to avoid the padding problem?


    --
    Alex Vinokur
    email: alex DOT vinokur AT gmail DOT com

    http://sourceforge.net/users/alexvn





  • Victor Bazarov

    #2
    Re: Casting struct to char array

    Alex Vinokur wrote:[color=blue]
    > "Richard Bos" <rlb@hoekstra-uitgeverij.nl> wrote in message news:4180f756.1 97032434@news.i ndividual.net.. . to news:comp.lang. c
    >[color=green]
    >>ben19777@hotm ail.com (Ben) wrote:[/color]
    >
    > [snip]
    >[color=green][color=darkred]
    >>>2) Structure casted into an array of char
    >>>typedef struct {
    >>>char name[20];
    >>>int age;
    >>>int id;
    >>>} person;
    >>>
    >>>person p = (person *) malloc(sizeof(p erson));
    >>>p.name="hell o";
    >>>p.age=2;
    >>>p.id=2;
    >>>
    >>>char *a;
    >>>a=(char *)p;[/color]
    >>
    >>No. You cannot cast a struct into a pointer. And what would you do this
    >>for, anyway? Do you suppose that the bytes represented by "hello"
    >>somehow form a valid pointer?
    >>I suspect you meant to access the struct itself _through_, not _as_, a
    >>pointer to char. In that case, you need to do
    >>
    >> a = (char *)&p;
    >>
    >>which is perfectly legal, and can be useful - though rarely. Beware the
    >>padding bytes!
    >>[/color]
    >
    > [snip]
    >
    > Is it possible to write 'operator char*()' inside the C++-structure that enables to avoid the padding problem?[/color]

    Which "padding problem" is it?

    V

    Comment

    • Alex Vinokur

      #3
      Re: Casting struct to char array


      "Victor Bazarov" <v.Abazarov@com Acast.net> wrote in message news:Bqygd.7722 $Ae.5313@newsre ad1.dllstx09.us .to.verio.net.. .[color=blue]
      > Alex Vinokur wrote:[color=green]
      > > "Richard Bos" <rlb@hoekstra-uitgeverij.nl> wrote in message news:4180f756.1 97032434@news.i ndividual.net.. . to news:comp.lang. c
      > >[color=darkred]
      > >>ben19777@hotm ail.com (Ben) wrote:[/color]
      > >
      > > [snip]
      > >[color=darkred]
      > >>>2) Structure casted into an array of char
      > >>>typedef struct {
      > >>>char name[20];
      > >>>int age;
      > >>>int id;
      > >>>} person;
      > >>>
      > >>>person p = (person *) malloc(sizeof(p erson));
      > >>>p.name="hell o";
      > >>>p.age=2;
      > >>>p.id=2;
      > >>>
      > >>>char *a;
      > >>>a=(char *)p;
      > >>
      > >>No. You cannot cast a struct into a pointer. And what would you do this
      > >>for, anyway? Do you suppose that the bytes represented by "hello"
      > >>somehow form a valid pointer?
      > >>I suspect you meant to access the struct itself _through_, not _as_, a
      > >>pointer to char. In that case, you need to do
      > >>
      > >> a = (char *)&p;
      > >>
      > >>which is perfectly legal, and can be useful - though rarely. Beware the
      > >>padding bytes!
      > >>[/color]
      > >
      > > [snip]
      > >
      > > Is it possible to write 'operator char*()' inside the C++-structure that enables to avoid the padding problem?[/color]
      >
      > Which "padding problem" is it?
      >
      > V[/color]


      --------- C++ code : BEGIN ---------
      // File foo.cpp
      #include <iostream>
      using namespace std;

      struct Foo1
      {
      char ch1;
      char ch2;
      short sh1;
      Foo1 () : ch1 ('a'), ch2('b'), sh1 (0x6364) {};

      };

      struct Foo2
      {
      char ch1;
      short sh1;
      char ch2;
      Foo2 () : ch1 ('a'), sh1 (0x6364), ch2('b') {};

      };


      #define SHOW(x,i) cout << #x << "[" << i << "] = " << x[i] << endl

      int main ()
      {
      Foo1 foo1;
      Foo2 foo2;
      char* charray1 = (char*)&foo1;
      char* charray2 = (char*)&foo2;

      cout << "Foo1" << endl;
      SHOW (charray1, 0);
      SHOW (charray1, 1);
      SHOW (charray1, 2);
      SHOW (charray1, 3);

      cout << endl;
      cout << "Foo2" << endl;
      SHOW (charray2, 0);
      SHOW (charray2, 1);
      SHOW (charray2, 2);
      SHOW (charray2, 3);
      SHOW (charray2, 4);

      return 0;
      }
      --------- C++ code : END -----------



      --------- Compilation & Run : BEGIN ---------

      $ g++ -v
      [omitted]
      gcc version 3.3.3 (cygwin special)


      $ g++ -W -Wall foo.cpp
      // No errors/warnings

      $ a

      Foo1
      charray1[0] = a
      charray1[1] = b
      charray1[2] = d
      charray1[3] = c

      Foo2
      charray2[0] = a
      charray2[1] = ~
      charray2[2] = d
      charray2[3] = c
      charray2[4] = b

      --------- Compilation & Run : END -----------

      We can see that ch2 from Foo1 and Foo2 is in the different places of charray1 and charray2
      because charray2[1] is a hole.


      --
      Alex Vinokur
      email: alex DOT vinokur AT gmail DOT com

      http://sourceforge.net/users/alexvn



      Comment

      • Victor Bazarov

        #4
        Re: Casting struct to char array

        Alex Vinokur wrote:[color=blue]
        > "Victor Bazarov" <v.Abazarov@com Acast.net> wrote in message news:Bqygd.7722 $Ae.5313@newsre ad1.dllstx09.us .to.verio.net.. .
        >[color=green]
        >>Alex Vinokur wrote:
        >>[color=darkred]
        >>>"Richard Bos" <rlb@hoekstra-uitgeverij.nl> wrote in message news:4180f756.1 97032434@news.i ndividual.net.. . to news:comp.lang. c
        >>>
        >>>
        >>>>ben19777@ho tmail.com (Ben) wrote:
        >>>
        >>>[snip]
        >>>
        >>>
        >>>>>2) Structure casted into an array of char
        >>>>>typedef struct {
        >>>>>char name[20];
        >>>>>int age;
        >>>>>int id;
        >>>>>} person;
        >>>>>
        >>>>>person p = (person *) malloc(sizeof(p erson));
        >>>>>p.name="he llo";
        >>>>>p.age=2;
        >>>>>p.id=2;
        >>>>>
        >>>>>char *a;
        >>>>>a=(char *)p;
        >>>>
        >>>>No. You cannot cast a struct into a pointer. And what would you do this
        >>>>for, anyway? Do you suppose that the bytes represented by "hello"
        >>>>somehow form a valid pointer?
        >>>>I suspect you meant to access the struct itself _through_, not _as_, a
        >>>>pointer to char. In that case, you need to do
        >>>>
        >>>> a = (char *)&p;
        >>>>
        >>>>which is perfectly legal, and can be useful - though rarely. Beware the
        >>>>padding bytes!
        >>>>
        >>>
        >>>[snip]
        >>>
        >>>Is it possible to write 'operator char*()' inside the C++-structure that enables to avoid the padding problem?[/color]
        >>
        >>Which "padding problem" is it?
        >>
        >>V[/color]
        >
        >
        >
        > --------- C++ code : BEGIN ---------
        > // File foo.cpp
        > #include <iostream>
        > using namespace std;
        >
        > struct Foo1
        > {
        > char ch1;
        > char ch2;
        > short sh1;
        > Foo1 () : ch1 ('a'), ch2('b'), sh1 (0x6364) {};
        >
        > };
        >
        > struct Foo2
        > {
        > char ch1;
        > short sh1;
        > char ch2;
        > Foo2 () : ch1 ('a'), sh1 (0x6364), ch2('b') {};
        >
        > };
        >
        > [...]
        >
        > --------- Compilation & Run : END -----------
        >
        > We can see that ch2 from Foo1 and Foo2 is in the different places of charray1 and charray2
        > because charray2[1] is a hole.[/color]

        OK, I'll bite. How is that a problem? If your struct is a POD, you may
        use 'offsetof' to figure out where exactly a member is, but if it's not
        POD, what use do you have for the "position"?

        V

        Comment

        • Alex Vinokur

          #5
          Re: Casting struct to char array


          "Victor Bazarov" <v.Abazarov@com Acast.net> wrote in message news:t8zgd.7727 $Ae.1489@newsre ad1.dllstx09.us .to.verio.net.. .[color=blue]
          > Alex Vinokur wrote:[color=green]
          > > "Victor Bazarov" <v.Abazarov@com Acast.net> wrote in message news:Bqygd.7722 $Ae.5313@newsre ad1.dllstx09.us .to.verio.net.. .
          > >[color=darkred]
          > >>Alex Vinokur wrote:
          > >>
          > >>>"Richard Bos" <rlb@hoekstra-uitgeverij.nl> wrote in message news:4180f756.1 97032434@news.i ndividual.net.. . to news:comp.lang. c
          > >>>
          > >>>
          > >>>>ben19777@ho tmail.com (Ben) wrote:
          > >>>
          > >>>[snip]
          > >>>
          > >>>
          > >>>>>2) Structure casted into an array of char
          > >>>>>typedef struct {
          > >>>>>char name[20];
          > >>>>>int age;
          > >>>>>int id;
          > >>>>>} person;
          > >>>>>
          > >>>>>person p = (person *) malloc(sizeof(p erson));
          > >>>>>p.name="he llo";
          > >>>>>p.age=2;
          > >>>>>p.id=2;
          > >>>>>
          > >>>>>char *a;
          > >>>>>a=(char *)p;
          > >>>>
          > >>>>No. You cannot cast a struct into a pointer. And what would you do this
          > >>>>for, anyway? Do you suppose that the bytes represented by "hello"
          > >>>>somehow form a valid pointer?
          > >>>>I suspect you meant to access the struct itself _through_, not _as_, a
          > >>>>pointer to char. In that case, you need to do
          > >>>>
          > >>>> a = (char *)&p;
          > >>>>
          > >>>>which is perfectly legal, and can be useful - though rarely. Beware the
          > >>>>padding bytes!
          > >>>>
          > >>>
          > >>>[snip]
          > >>>
          > >>>Is it possible to write 'operator char*()' inside the C++-structure that enables to avoid the padding problem?
          > >>
          > >>Which "padding problem" is it?
          > >>
          > >>V[/color]
          > >
          > >
          > >
          > > --------- C++ code : BEGIN ---------
          > > // File foo.cpp
          > > #include <iostream>
          > > using namespace std;
          > >
          > > struct Foo1
          > > {
          > > char ch1;
          > > char ch2;
          > > short sh1;
          > > Foo1 () : ch1 ('a'), ch2('b'), sh1 (0x6364) {};
          > >
          > > };
          > >
          > > struct Foo2
          > > {
          > > char ch1;
          > > short sh1;
          > > char ch2;
          > > Foo2 () : ch1 ('a'), sh1 (0x6364), ch2('b') {};
          > >
          > > };
          > >
          > > [...]
          > >
          > > --------- Compilation & Run : END -----------
          > >
          > > We can see that ch2 from Foo1 and Foo2 is in the different places of charray1 and charray2
          > > because charray2[1] is a hole.[/color]
          >
          > OK, I'll bite. How is that a problem? If your struct is a POD, you may
          > use 'offsetof' to figure out where exactly a member is, but if it's not
          > POD, what use do you have for the "position"?
          >
          > V[/color]

          Something like ?


          --------- C++ code : BEGIN ---------

          #include <iostream>
          #include <cassert>
          using namespace std;

          struct Foo
          {
          char ch1;
          short sh;

          char ch2;
          char cstr[3];

          char ch3;

          Foo () : ch1 ('a'), sh (0x6667), ch2('b'), ch3('c') { strcpy (cstr, "de");};

          operator char *()
          {
          const int pure_size (sizeof(ch1) + sizeof(sh) + sizeof(ch2) + strlen(cstr) + sizeof(ch3) + 1);
          char* ret_ptr = new char [pure_size];

          int i = 0;
          ret_ptr[i++] = ch1;

          char* tmp_ptr = (char*)&sh;
          for (int j = 0; j < sizeof(sh); j++) ret_ptr[i++] = *tmp_ptr++;
          ret_ptr[i++] = ch2;

          for (int j = 0; j < strlen(cstr); j++) ret_ptr[i++] = cstr[j];

          ret_ptr[i++] = ch3;
          ret_ptr[i] = 0;
          assert (i < pure_size);

          return ret_ptr;

          };

          };


          #define SHOW(x,i) cout << #x << "[" << i << "] : ch = " << x[i] << "; hex = " << hex << uint (x[i]) << endl

          int main ()
          {
          Foo foo;
          char* charray1 = (char*)&foo;
          char* charray2 = (char*)foo;

          cout << "Regular (char*)" << endl;
          for (int i = 0; i < sizeof (foo); i++) SHOW (charray1, i);

          cout << endl;
          cout << "Overloaded (char*)" << endl;
          for (int i = 0; i < sizeof (foo); i++) SHOW (charray2, i);

          return 0;
          }

          --------- C++ code : END -----------



          --------- Compilation & Run : BEGIN ---------

          $ g++ -v
          [omitted]
          gcc version 3.3.3 (cygwin special)


          $ g++ foo.cpp
          // No errors/warnings

          $ a

          Regular (char*)
          charray1[0] : ch = a; hex = 61
          charray1[1] : ch = ; hex = 3
          charray1[2] : ch = g; hex = 67
          charray1[3] : ch = f; hex = 66
          charray1[4] : ch = b; hex = 62
          charray1[5] : ch = d; hex = 64
          charray1[6] : ch = e; hex = 65
          charray1[7] : ch = ; hex = 0
          charray1[8] : ch = c; hex = 63
          charray1[9] : ch = ð; hex = fffffff0

          Overloaded (char*)
          charray2[0] : ch = a; hex = 61
          charray2[1] : ch = g; hex = 67
          charray2[2] : ch = f; hex = 66
          charray2[3] : ch = b; hex = 62
          charray2[4] : ch = d; hex = 64
          charray2[5] : ch = e; hex = 65
          charray2[6] : ch = c; hex = 63
          charray2[7] : ch = ; hex = 0
          charray2[8] : ch = ; hex = 0
          charray2[9] : ch = ; hex = 0

          --------- Compilation & Run : END -----------


          --
          Alex Vinokur
          email: alex DOT vinokur AT gmail DOT com

          http://sourceforge.net/users/alexvn




          Comment

          • Alex Vinokur

            #6
            Re: Casting struct to char array


            "Alex Vinokur" <alexvn@big-foot.com> wrote in message news:2uh2isF2ac qqdU1@uni-berlin.de...
            [snip]
            -----------------------
            For not POD[color=blue]
            > Something like ?[/color]
            -----------------------
            [snip]


            For POD

            --------- C++ code : BEGIN ---------
            #include <iostream>
            #include <cassert>
            using namespace std;

            struct Foo
            {
            char ch1;
            short sh;

            char ch2;
            char cstr[3];

            char ch3;

            };

            char* get_as_cstr(con st Foo& foo_i)
            {
            const int pure_size (sizeof(foo_i.c h1) + sizeof(foo_i.sh ) + sizeof(foo_i.ch 2) + strlen(foo_i.cs tr) + sizeof(foo_i.ch 3) + 1);
            char* ret_ptr = new char [pure_size];

            int i = 0;
            ret_ptr[i++] = foo_i.ch1;

            char* tmp_ptr = (char*)&foo_i.s h;
            for (int j = 0; j < sizeof(foo_i.sh ); j++) ret_ptr[i++] = *tmp_ptr++;
            ret_ptr[i++] = foo_i.ch2;

            for (int j = 0; j < strlen(foo_i.cs tr); j++) ret_ptr[i++] = foo_i.cstr[j];

            ret_ptr[i++] = foo_i.ch3;
            ret_ptr[i] = 0;
            assert (i < pure_size);

            return ret_ptr;
            }


            #define SHOW(x,i) cout << #x << "[" << i << "] : ch = " << x[i] << "; hex = " << hex << uint (x[i]) << endl

            int main ()
            {
            Foo foo;
            foo.ch1 = 'a';
            foo.sh = 0x6667;
            foo.ch2 = 'b';
            strcpy (foo.cstr, "de");
            foo.ch3 = 'c';

            char* charray1 = (char*)&foo;
            char* charray2 = get_as_cstr (foo);

            cout << "POD : Regular (char*)" << endl;
            for (int i = 0; i < sizeof (foo); i++) SHOW (charray1, i);

            cout << endl;
            cout << "POD : Function get_as_cstr" << endl;
            for (int i = 0; i < sizeof (foo); i++) SHOW (charray2, i);

            return 0;
            }


            --------- C++ code : END -----------



            --------- Compilation & Run : BEGIN ---------

            $ g++ -v
            [omitted]
            gcc version 3.3.3 (cygwin special)


            $ g++ foo.cpp
            // No errors/warnings

            $ a

            POD : Regular (char*)
            charray1[0] : ch = a; hex = 61
            charray1[1] : ch = ; hex = 3
            charray1[2] : ch = g; hex = 67
            charray1[3] : ch = f; hex = 66
            charray1[4] : ch = b; hex = 62
            charray1[5] : ch = d; hex = 64
            charray1[6] : ch = e; hex = 65
            charray1[7] : ch = ; hex = 0
            charray1[8] : ch = c; hex = 63
            charray1[9] : ch = ð; hex = fffffff0

            POD : Function get_as_cstr
            charray2[0] : ch = a; hex = 61
            charray2[1] : ch = g; hex = 67
            charray2[2] : ch = f; hex = 66
            charray2[3] : ch = b; hex = 62
            charray2[4] : ch = d; hex = 64
            charray2[5] : ch = e; hex = 65
            charray2[6] : ch = c; hex = 63
            charray2[7] : ch = ; hex = 0
            charray2[8] : ch = ; hex = 0
            charray2[9] : ch = ; hex = 0

            --------- Compilation & Run : END -----------


            --
            Alex Vinokur
            email: alex DOT vinokur AT gmail DOT com

            http://sourceforge.net/users/alexvn



            Comment

            Working...