Segment : offset of struct.

A

asm_fool

In the following code:

struct node
{
char p[20];
struct node *next;
};
main()
{
struct node p;
printf("%d \n",sizeof p.next->p);
}
I am getting the output as 20, which is correct. Ok, taking the
account of segment and offset of struct the size of the above struct
is 20 + 4 = 24. Assuming the struct memory address starts from 2000
and adding a 20+4 values we get as:

Seg : off (of whole struct)
2000:2000
2000:2001
2000:2002
….
….
….
2000:2014 (in hex)
seg : off (*next's value)
2004:2015
2004:2016
2004:2017
2004:2018

Is the above form of struct addressing is correct? Will the address of
seg:eek:ff of the next object starts from new address? If yes, then don't
we have another set of seg:eek:ff of
Struct->next->next's value like a mirror in front of a mirror?
 
A

asm_fool

Robert W Hand said:
In the following code:

struct node
{
char p[20];
struct node *next;
};
main()

main returns an int.
{
struct node p;
printf("%d \n",sizeof p.next->p);
}
I am getting the output as 20, which is correct. Ok, taking the

You have printed out the size of the p field of p via the next pointer
field. For exposition, I would choose different names.

Ok, I have changed the code.

#include <stddef.h>
struct node
{
char p[20];
struct node *next;
};
main()
{
struct node p;
printf("%d \n",sizeof p);
}

I am getting 24 as the out put.

How can I access a specific byte of a struct?


What about the second part of my question?

Please answer.
 
M

Mark McIntyre

In the following code:

struct node
{
char p[20];
struct node *next;
};
main()
{
struct node p;
printf("%d \n",sizeof p.next->p);
}
I am getting the output as 20, which is correct.

Is it? p.next->p is a pointer to a struct node. But you didn't point
it _at_ anything, so I suspect in fact you have an error.
Ok, taking the
account of segment and offset of struct the size of the above struct
is 20 + 4 = 24.

No, there can be padding between structure members, and (ISTR) at the
end too.
Assuming the struct memory address starts from 2000
and adding a 20+4 values we get as:

and everything below here is not C, but Intel -specific hardware
stuff.
 
R

Robert W Hand

Ok, I have changed the code.

#include <stddef.h>
struct node
{
char p[20];
struct node *next;
};
main()
{
struct node p;
printf("%d \n",sizeof p);
}

I am getting 24 as the out put.

How can I access a specific byte of a struct?

You are skating on pretty thin ice with that question. There is
something called padding that may allow the various fields of a
structure to be aligned properly. So a specific byte may be padding.
Furthermore, these are memory objects that have type. To address a
single byte may lead to corruption of the values in those objects.

If you wish to work with offsets into a structure, then you should
look into offsetof, a macro defined in stddef.h. Here is a short
example sans headers:

struct A
{
int a;
char b[21];
int c;
};

int main(void)
{
struct A aa;
printf("%u\n", offsetof(struct A, a));
printf("%u\n", offsetof(struct A, b));
printf("%u\n", offsetof(struct A, c));
return 0;
}

The output is:

0
4
28

On my system, I know that int has size of 4. So a is coterminus with
the structure. b is offset by four bytes as expected. But c is offset
by 28, not the expected 25. Presumably padding has been inserted to
allow c to align properly on an int boundary.
What about the second part of my question?

Please answer.

Without numbering, it is hard to know what is the second part. I
actually thought that I skipped to the second part with my answer.

Best wishes,

Bob
 
D

Dave Thompson

In the following code:

struct node
{
char p[20];
struct node *next;
};
main()
{
struct node p;
printf("%d \n",sizeof p.next->p);
}

%d expects a (signed) int, but sizeof yields a value of type size_t,
which cannot be int (because it must be unsigned); on some
implementations a size_t value will be compatible with a
(positive) int value, even as a *printf argument (which is not
required even where they have the same width and values
in the intersection must be compatible in memory).
Better to cast (here to int) or in C99 use %zu.
Is it? p.next->p is a pointer to a struct node. But you didn't point
it _at_ anything, so I suspect in fact you have an error.
No, it's OK; the operand of sizeof is not evaluated unless it is/has
a Variable Length Array type, which this doesn't. It is however
unnecessarily complicated; sizeof p.p would accomplish the same thing.
(Personally I don't think I would name a char[] field 'p'.)
No, there can be padding between structure members, and (ISTR) at the
end too.
There can be in general, but obviously on this implementation
for this struct there wasn't, and in fact I'd expect on most if not
all implementations there won't be. We can't properly say that
the struct (type) size unequivocally 'is' 24, but we can say it is 24
on this implementation -- and on a given implementation all structs
of the same type have the same layout, and in particular size.


- David.Thompson1 at worldnet.att.net
 
D

Dave Thompson

Fine point -- I said "the same type", not similar types. C identifies
struct etc. types by tag, not content. Within a translation unit,
only declarations of the same tag at the same scope, or the single
definition of an untagged struct union or enum, are the same type;
this is why first using a tag in prototype scope is technically wrong
although almost always harmless. Across t.u.s, struct types with the
same tag if any and members must be compatible = have the same layout,
and I could and perhaps should have said "same or compatible type".
Well, probably. Consider the effect of implementation defined pragmas
to change packing rules, possibly hidden in headers. This renders even
apparently identical structs potentially of different sizes;

someheader.h:
#pragma pack(1)

test.c
typedef struct foo {int x; char y[5];double z;}foo;
#include "someheader.h"
typedef struct bar {int x; char y[5];double z;}bar;

foo and bar, although identical to the programmer, have different
sizes.

Technically an implementation would even be allowed to use a different
layout for the same members but different (present) tags, although it
would be extremely silly to do so. And for completeness a compiler
can be influenced by other options (e.g. command line or config) or
(e.g. gcc) attributes as well as pragmas.

- David.Thompson1 at worldnet.att.net
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,996
Messages
2,570,237
Members
46,825
Latest member
VernonQuy6

Latest Threads

Top