473,395 Members | 1,694 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Problem with structs and mem. allocation

Hi. Have a look at this program:

struct tmp {
short a;
int b;
short c;
};

int main()
{
ofstream f("tmp.bin",ios::binary);
tmp t; t.a=5; t.b=2000; t.c=2;

f.write((const char*)&t.a,sizeof(short));
f.write((const char*)&t.b,sizeof(int));
f.write((const char*)&t.c,sizeof(char));
f.close();

ifstream g("tmp.bin", ios::binary);
tmp s;

g.read((char*)&s,sizeof(tmp));

cout << s.a << " " << s.b << " " << s.c << " " << endl;
cout << &s.a << " " << &s.b << " " << &s.c << " " << endl;
g.close();
}

The output should be (supposing &s==0x22fd48):

5 2000 2
0x22fd48 0x22fd4a 0x22fd4e

But the actual output is:

5 131072 -2764
0x22fd48 0x22fd4c 0x22fd50

So the problem is that the parts of the struct are not continuous in
memory!!! I mean, s.b should start 2 bytes after &s but actually it starts
after 4 bytes. That's why the g.read(...) doesn't work.

I tried:

but: cout << *((int*)((char*) (&s)+sizeof(short)))

and it output 2000.

In conclusion: &s+sizeof(s.a) != &s.b

Is all this my mistake or am I right??? I'm looking forward to an
explanation.

Thanks!


Jul 22 '05 #1
7 1486

"Nafai" <na*******@yahoo.es> wrote in message
news:1q**********************@telenews.teleline.es ...
Hi. Have a look at this program:

struct tmp {
short a;
int b;
short c;
};

int main()
{
ofstream f("tmp.bin",ios::binary);
tmp t; t.a=5; t.b=2000; t.c=2;

f.write((const char*)&t.a,sizeof(short));
f.write((const char*)&t.b,sizeof(int));
f.write((const char*)&t.c,sizeof(char));
f.close();

ifstream g("tmp.bin", ios::binary);
tmp s;

g.read((char*)&s,sizeof(tmp));

cout << s.a << " " << s.b << " " << s.c << " " << endl;
cout << &s.a << " " << &s.b << " " << &s.c << " " << endl;
g.close();
}

The output should be (supposing &s==0x22fd48):

5 2000 2
0x22fd48 0x22fd4a 0x22fd4e

But the actual output is:

5 131072 -2764
0x22fd48 0x22fd4c 0x22fd50

So the problem is that the parts of the struct are not continuous in
memory!!! I mean, s.b should start 2 bytes after &s but actually it starts
after 4 bytes. That's why the g.read(...) doesn't work.
Right. Now what made you think that they had to be contiguous in memory?

I tried:

but: cout << *((int*)((char*) (&s)+sizeof(short)))

and it output 2000.

In conclusion: &s+sizeof(s.a) != &s.b

Is all this my mistake or am I right??? I'm looking forward to an
explanation.


Compilers are allowed to add 'padding' between the data members of a struct
or class. They do this for efficiency reasons. Most compilers will have
compiler specific options to alter the padding or to turn it off entirely.

Alternatively you could read your data in the same way that you wrote it,
that would be the sensible thing to do.

john
Jul 22 '05 #2
>>
But the actual output is:

5 131072 -2764
0x22fd48 0x22fd4c 0x22fd50

So the problem is that the parts of the struct are not continuous in
memory!!! I mean, s.b should start 2 bytes after &s but actually it
starts
after 4 bytes. That's why the g.read(...) doesn't work.


Right. Now what made you think that they had to be contiguous in memory?


I have seen most times things like g.read((char*)&s,sizeof(tmp)); to read a
full struct with one instruction.
Jul 22 '05 #3

"Nafai" <na*******@yahoo.es> wrote in message
news:EZ**********************@telenews.teleline.es ...

But the actual output is:

5 131072 -2764
0x22fd48 0x22fd4c 0x22fd50

So the problem is that the parts of the struct are not continuous in
memory!!! I mean, s.b should start 2 bytes after &s but actually it
starts
after 4 bytes. That's why the g.read(...) doesn't work.
Right. Now what made you think that they had to be contiguous in memory?


I have seen most times things like g.read((char*)&s,sizeof(tmp)); to read

a full struct with one instruction.


That code is OK providing that you read and write in the same way. Your
mistake was reading one way and writing another. Providing you don't mind
any padding bytes being written out to the file, you can read and write a
whole struct in one go.

And of course any binary read or write is not portable across machines,
compilers, etc. etc.

john
Jul 22 '05 #4
Nafai wrote:

But the actual output is:

5 131072 -2764
0x22fd48 0x22fd4c 0x22fd50

So the problem is that the parts of the struct are not continuous in
memory!!! I mean, s.b should start 2 bytes after &s but actually it
starts
after 4 bytes. That's why the g.read(...) doesn't work.


Right. Now what made you think that they had to be contiguous in memory?


I have seen most times things like g.read((char*)&s,sizeof(tmp)); to read a
full struct with one instruction.


Right. Now search the same program and you will find that those programs
also write a struct in one rush

g.write( char*)&s, sizeof(tmp) );

and *never* by writing each struct member individually.
(Except of course when the programmer was aware of the padding issue
and took it into account. But thats rare).

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #5
I came across this problem when reading a BMP file. I defined a struct for
the header and I got into trouble when reading the whole struct. So I have
to read each element of the header (more than 20) one by one? Isn't there
any easier way?
"Karl Heinz Buchegger" <kb******@gascad.at> escribió en el mensaje
news:41***************@gascad.at...
Nafai wrote:
>>
>> But the actual output is:
>>
>> 5 131072 -2764
>> 0x22fd48 0x22fd4c 0x22fd50
>>
>> So the problem is that the parts of the struct are not continuous in
>> memory!!! I mean, s.b should start 2 bytes after &s but actually it
>> starts
>> after 4 bytes. That's why the g.read(...) doesn't work.
>
> Right. Now what made you think that they had to be contiguous in
> memory?
>


I have seen most times things like g.read((char*)&s,sizeof(tmp)); to read
a
full struct with one instruction.


Right. Now search the same program and you will find that those programs
also write a struct in one rush

g.write( char*)&s, sizeof(tmp) );

and *never* by writing each struct member individually.
(Except of course when the programmer was aware of the padding issue
and took it into account. But thats rare).

--
Karl Heinz Buchegger
kb******@gascad.at

Jul 22 '05 #6
Nafai wrote:
I came across this problem when reading a BMP file. I defined a struct for
the header and I got into trouble when reading the whole struct. So I have
to read each element of the header (more than 20) one by one? Isn't there
any easier way?


Write a file that describes the format of the header, and write a program
that reads this file and generates the code for reading the header.

Of course is more work, but is reusable.

--
Salu2
Jul 22 '05 #7

"Nafai" <na*******@yahoo.es> wrote in message
news:zr**********************@telenews.teleline.es ...
I came across this problem when reading a BMP file. I defined a struct for
the header and I got into trouble when reading the whole struct. So I have
to read each element of the header (more than 20) one by one? Isn't there
any easier way?


Well to be strictly portable you have to read the file one byte at a time,
not just one field at a time. How do you know that the format of an integer
in the BMP file (say) corresponds to the format of an int in your compiler?

If you don't mind not being portable then you should look at compiler
options or pragmas that will allow you to control the padding in your
struct. Then you can read the whole struct in one go.

john
Jul 22 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
by: Roman Hartmann | last post by:
hello, I do have a question regarding structs. I have a struct (profil) which has a pointer to another struct (point). The struct profil stores the coordinates of points. The problem is that I...
10
by: Patricia Van Hise | last post by:
Is it possible to access a field of a struct which is a field of another struct? Ex. struct subStr{ int num1; int num2; }; struct myStr { int num3; subStr *lock; };
6
by: Matthew Jakeman | last post by:
If i create a cruct like so : struct test{ char *var1 ; int var2 ; short var3 ; } and i want to allocate it memory, should i allocate enough to hold the max amount of data that will go...
30
by: stephen henry | last post by:
Hi all, I have a question that I'm having difficulty answering. If I have a struct: typedef struct my_struct_tag{ struct my_other_struct *other; } my_struct_tag
7
by: boss_bhat | last post by:
Hi all , I am beginner to C programming. I have a defined astructure like the following, and i am using aliases for the different data types in the structure, typedef struct _NAME_INFO {...
6
by: Tom | last post by:
I try to write a simple tcp based job queue server. It's purpose is to get commands from a client and store them in a queue (STL). The server has a thread which checks periodically the queue,...
61
by: Marty | last post by:
I am new to C# and to structs so this could be easy or just not possible. I have a struct defined called Branch If I use Branch myBranch = new Branch(i); // everything works If I use Branch...
4
by: veera sekhar kota | last post by:
I read structs are stored at stack area or inline-heap based objects. What is meant by inline-heap based objects? I didnt get that. Thanks, Veera.
12
by: Venkataramana | last post by:
Hi Can anyone tell me how C# allocates memory for structs in C#? I am having problems figuring out how much memory will be allocated. Consider the following snippet struct S1 { int i;...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.