Pointer subtraction

K

Kevin C.

udt_list *g_list = calloc(1, LIST_SIZE);
udt_entry *entry = get_entry(); // returns a pointer to some address in
g_list
int numbytes = (char*)entry - (char*)g_list; // supposed to be offset in
bytes

But numbytes is -240. Can someone explain why?
 
K

Karthik

Kevin said:
udt_list *g_list = calloc(1, LIST_SIZE);
udt_entry *entry = get_entry(); // returns a pointer to some address in
g_list
int numbytes = (char*)entry - (char*)g_list;

// supposed to be offset in bytes

Can't get dangerous than this line. You are subtracting char * and
assigning to an integer.
If you can let us know the precise intentions before doing this, this
n.g. can probably help. Letz know the bigger picture.
 
M

Mac

udt_list *g_list = calloc(1, LIST_SIZE);
udt_entry *entry = get_entry(); // returns a pointer to some address in
g_list
int numbytes = (char*)entry - (char*)g_list; // supposed to be offset in
bytes

But numbytes is -240. Can someone explain why?

You should declare numbytes to be a ptrdiff_t, a type which is defined in
stddef.h.

Personally, I would subtract like types without a cast, then multiply by
the sizeof the type to get the byte offset.

I doubt that the conversion to plain int is causing you a problem, though.
More likely, your assumption about g_list is wrong. Since you don't
provide any definitions of types and so on, it is impossible to
troubleshoot any further than that, AFAICT.

--Mac
 
J

John Carson

Kevin C. said:
udt_list *g_list = calloc(1, LIST_SIZE);
udt_entry *entry = get_entry(); // returns a pointer to some address
in g_list
int numbytes = (char*)entry - (char*)g_list; // supposed to be offset
in bytes

But numbytes is -240. Can someone explain why?

The fact that get_entry() doesn't take an argument is a clue that it doesn't
do what you think it does.

The following shows an example that works. It retrieves the offset of the
style field in a CREATESTRUCT struct. Compare it to what you are doing and
you should be able to figure out where you are going wrong.

LONG *GetStyleAddress(CREATESTRUCT * pcs)
{
return &pcs->style;
}

int main()
{
CREATESTRUCT *pcs = (CREATESTRUCT*)calloc(1, sizeofCREATESTRUCT));
LONG *pstyle = GetStyleAddress(pcs);
int numbytes = (char*)pstyle - (char*)pcs;
return 0;
}

If you were working with a linked list, then there is no necessary reason
for later list elements to have a higher address than earlier elements, but
the code you have supplied isn't consistent with a linked list.
 
I

Irrwahn Grausewitz

I seriously doubt that. Hint: how does get_entry know about g_list?

Obviously entry is _not_ a pointer into the same array. You invoked
UB, the result could've been anything.
You should declare numbytes to be a ptrdiff_t, a type which is defined in
stddef.h.
Indeed.

Personally, I would subtract like types without a cast, then multiply by
the sizeof the type to get the byte offset.

Bad idea: subtracting pointers of incompatible object type is a
constraint violation, even if both pointers happen to point into
(or one past) the same array object.

<snip>

Regards
 
M

Mac

Bad idea: subtracting pointers of incompatible object type is a
constraint violation, even if both pointers happen to point into
(or one past) the same array object.

When I wrote "like types" I meant to convey the idea that I would subtract
only if the types were the same. I didn't word it very clearly.

--Mac
 

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,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top