By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,411 Members | 1,042 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,411 IT Pros & Developers. It's quick & easy.

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

P: n/a

"Richard Bos" <rl*@hoekstra-uitgeverij.nl> wrote in message news:41****************@news.individual.net... to news:comp.lang.c
be******@hotmail.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

Jul 22 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Alex Vinokur wrote:
"Richard Bos" <rl*@hoekstra-uitgeverij.nl> wrote in message news:41****************@news.individual.net... to news:comp.lang.c
be******@hotmail.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?


Which "padding problem" is it?

V
Jul 22 '05 #2

P: n/a

"Victor Bazarov" <v.********@comAcast.net> wrote in message news:Bq****************@newsread1.dllstx09.us.to.v erio.net...
Alex Vinokur wrote:
"Richard Bos" <rl*@hoekstra-uitgeverij.nl> wrote in message news:41****************@news.individual.net... to news:comp.lang.c
be******@hotmail.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?


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

Jul 22 '05 #3

P: n/a
Alex Vinokur wrote:
"Victor Bazarov" <v.********@comAcast.net> wrote in message news:Bq****************@newsread1.dllstx09.us.to.v erio.net...
Alex Vinokur wrote:
"Richard Bos" <rl*@hoekstra-uitgeverij.nl> wrote in message news:41****************@news.individual.net... to news:comp.lang.c
be******@hotmail.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?


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
Jul 22 '05 #4

P: n/a

"Victor Bazarov" <v.********@comAcast.net> wrote in message news:t8****************@newsread1.dllstx09.us.to.v erio.net...
Alex Vinokur wrote:
"Victor Bazarov" <v.********@comAcast.net> wrote in message news:Bq****************@newsread1.dllstx09.us.to.v erio.net...
Alex Vinokur wrote:

"Richard Bos" <rl*@hoekstra-uitgeverij.nl> wrote in message news:41****************@news.individual.net... to news:comp.lang.c
>be******@hotmail.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?

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


Jul 22 '05 #5

P: n/a

"Alex Vinokur" <al****@big-foot.com> wrote in message news:2u*************@uni-berlin.de...
[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[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

Jul 22 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.