C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

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

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++)
View previous topic :: View next topic  
Author Message
Alex Vinokur
Guest





PostPosted: Fri Oct 29, 2004 9:09 pm    Post subject: Casting struct to char array (was: Linked List problem) Reply with quote




"Richard Bos" <rlb (AT) hoekstra-uitgeverij (DOT) nl> wrote

Quote:
ben19777 (AT) hotmail (DOT) 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(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






Back to top
Victor Bazarov
Guest





PostPosted: Fri Oct 29, 2004 9:16 pm    Post subject: Re: Casting struct to char array Reply with quote



Alex Vinokur wrote:
Quote:
"Richard Bos" <rlb (AT) hoekstra-uitgeverij (DOT) nl> wrote


[email]ben19777 (AT) hotmail (DOT) com[/email] (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

Back to top
Alex Vinokur
Guest





PostPosted: Fri Oct 29, 2004 9:51 pm    Post subject: Re: Casting struct to char array Reply with quote




"Victor Bazarov" <v.Abazarov (AT) comAcast (DOT) net> wrote

Quote:
Alex Vinokur wrote:
"Richard Bos" <rlb (AT) hoekstra-uitgeverij (DOT) nl> wrote


[email]ben19777 (AT) hotmail (DOT) com[/email] (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[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://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn




Back to top
Victor Bazarov
Guest





PostPosted: Fri Oct 29, 2004 10:05 pm    Post subject: Re: Casting struct to char array Reply with quote

Alex Vinokur wrote:
Quote:
"Victor Bazarov" <v.Abazarov (AT) comAcast (DOT) net> wrote


Alex Vinokur wrote:

"Richard Bos" <rlb (AT) hoekstra-uitgeverij (DOT) nl> wrote



[email]ben19777 (AT) hotmail (DOT) com[/email] (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 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

Back to top
Alex Vinokur
Guest





PostPosted: Sat Oct 30, 2004 8:43 am    Post subject: Re: Casting struct to char array Reply with quote


"Victor Bazarov" <v.Abazarov (AT) comAcast (DOT) net> wrote

Quote:
Alex Vinokur wrote:
"Victor Bazarov" <v.Abazarov (AT) comAcast (DOT) net> wrote


Alex Vinokur wrote:

"Richard Bos" <rlb (AT) hoekstra-uitgeverij (DOT) nl> wrote



[email]ben19777 (AT) hotmail (DOT) com[/email] (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 #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://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn





Back to top
Alex Vinokur
Guest





PostPosted: Sat Oct 30, 2004 9:06 am    Post subject: Re: Casting struct to char array Reply with quote


"Alex Vinokur" <alexvn (AT) big-foot (DOT) com> wrote

[snip]
-----------------------
For not POD
Quote:
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[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://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn




Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.