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

Discussion in 'C++' started by Alex Vinokur, Oct 29, 2004.

  1. Alex Vinokur

    Alex Vinokur Guest

    "Richard Bos" <> wrote in message news:... to news:comp.lang.c
    > (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(person));
    > > p.name="hello";
    > > 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?


    --
    Alex Vinokur
    email: alex DOT vinokur AT gmail DOT com
    http://mathforum.org/library/view/10978.html
    http://sourceforge.net/users/alexvn
     
    Alex Vinokur, Oct 29, 2004
    #1
    1. Advertising

  2. Re: Casting struct to char array

    Alex Vinokur wrote:
    > "Richard Bos" <> wrote in message news:... to news:comp.lang.c
    >
    >> (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(person));
    >>>p.name="hello";
    >>>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
     
    Victor Bazarov, Oct 29, 2004
    #2
    1. Advertising

  3. Alex Vinokur

    Alex Vinokur Guest

    Re: Casting struct to char array

    "Victor Bazarov" <> wrote in message news:Bqygd.7722$09.us.to.verio.net...
    > Alex Vinokur wrote:
    > > "Richard Bos" <> wrote in message news:... to news:comp.lang.c
    > >
    > >> (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(person));
    > >>>p.name="hello";
    > >>>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



    --------- 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 << 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://mathforum.org/library/view/10978.html
    http://sourceforge.net/users/alexvn
     
    Alex Vinokur, Oct 29, 2004
    #3
  4. Re: Casting struct to char array

    Alex Vinokur wrote:
    > "Victor Bazarov" <> wrote in message news:Bqygd.7722$09.us.to.verio.net...
    >
    >>Alex Vinokur wrote:
    >>
    >>>"Richard Bos" <> wrote in message news:... to news:comp.lang.c
    >>>
    >>>
    >>>> (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(person));
    >>>>>p.name="hello";
    >>>>>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

    >
    >
    >
    > --------- 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.


    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
     
    Victor Bazarov, Oct 29, 2004
    #4
  5. Alex Vinokur

    Alex Vinokur Guest

    Re: Casting struct to char array

    "Victor Bazarov" <> wrote in message news:t8zgd.7727$09.us.to.verio.net...
    > Alex Vinokur wrote:
    > > "Victor Bazarov" <> wrote in message news:Bqygd.7722$09.us.to.verio.net...
    > >
    > >>Alex Vinokur wrote:
    > >>
    > >>>"Richard Bos" <> wrote in message news:... to news:comp.lang.c
    > >>>
    > >>>
    > >>>> (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(person));
    > >>>>>p.name="hello";
    > >>>>>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

    > >
    > >
    > >
    > > --------- 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.

    >
    > 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


    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 = 0;
    assert (i < pure_size);

    return ret_ptr;

    };

    };


    #define SHOW(x,i) cout << #x << "[" << i << "] : ch = " << x << "; hex = " << hex << uint (x) << 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://mathforum.org/library/view/10978.html
    http://sourceforge.net/users/alexvn
     
    Alex Vinokur, Oct 30, 2004
    #5
  6. Alex Vinokur

    Alex Vinokur Guest

    Re: Casting struct to char array

    "Alex Vinokur" <> wrote in message news:...
    [snip]
    -----------------------
    For not POD
    > Something like ?

    -----------------------
    [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(const Foo& foo_i)
    {
    const int pure_size (sizeof(foo_i.ch1) + sizeof(foo_i.sh) + sizeof(foo_i.ch2) + strlen(foo_i.cstr) + sizeof(foo_i.ch3) + 1);
    char* ret_ptr = new char [pure_size];

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

    char* tmp_ptr = (char*)&foo_i.sh;
    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.cstr); j++) ret_ptr[i++] = foo_i.cstr[j];

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

    return ret_ptr;
    }


    #define SHOW(x,i) cout << #x << "[" << i << "] : ch = " << x << "; hex = " << hex << uint (x) << 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://mathforum.org/library/view/10978.html
    http://sourceforge.net/users/alexvn
     
    Alex Vinokur, Oct 30, 2004
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Chris Ritchey
    Replies:
    7
    Views:
    510
    emerth
    Jul 10, 2003
  2. Chris Ritchey

    Generating a char* from a linked list of linked lists

    Chris Ritchey, Jul 9, 2003, in forum: C Programming
    Replies:
    7
    Views:
    501
    emerth
    Jul 10, 2003
  3. lovecreatesbeauty
    Replies:
    1
    Views:
    1,149
    Ian Collins
    May 9, 2006
  4. fool
    Replies:
    14
    Views:
    541
    Barry Schwarz
    Jul 3, 2006
  5. Tuan  Bui
    Replies:
    14
    Views:
    524
    it_says_BALLS_on_your forehead
    Jul 29, 2005
Loading...

Share This Page