# Pointer subtraction

Discussion in 'C Programming' started by Kevin C., May 7, 2004.

1. ### Kevin C.Guest

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?

Kevin C., May 7, 2004

2. ### KarthikGuest

Kevin C. wrote:
> 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.

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

--
Karthik.
Humans please 'removeme_' for my real email.

Karthik, May 7, 2004

3. ### MacGuest

On Fri, 07 May 2004 02:37:12 +0000, Kevin C. wrote:

> 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.
provide any definitions of types and so on, it is impossible to
troubleshoot any further than that, AFAICT.

--Mac

Mac, May 7, 2004
4. ### John CarsonGuest

"Kevin C." <> wrote in message
news:sDCmc.45734\$
> 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.

{
return &pcs->style;
}

int main()
{
CREATESTRUCT *pcs = (CREATESTRUCT*)calloc(1, sizeofCREATESTRUCT));
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.

--
John Carson

John Carson, May 7, 2004
5. ### Irrwahn GrausewitzGuest

"Mac" <> wrote:
>On Fri, 07 May 2004 02:37:12 +0000, Kevin C. wrote:
>
>> udt_list *g_list = calloc(1, LIST_SIZE);
>> udt_entry *entry = get_entry(); // returns a pointer to some address in
>> g_list

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

>> int numbytes = (char*)entry - (char*)g_list; // supposed to be offset in
>> bytes
>>
>> But numbytes is -240. Can someone explain why?

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
--
Irrwahn Grausewitz ()
welcome to clc: http://www.ungerhu.com/jxh/clc.welcome.txt
clc faq-list : http://www.faqs.org/faqs/C-faq/faq/
clc OT guide : http://benpfaff.org/writings/clc/off-topic.html

Irrwahn Grausewitz, May 7, 2004
6. ### MacGuest

On Fri, 07 May 2004 09:59:27 +0200, Irrwahn Grausewitz wrote:

> "Mac" <> wrote:

[snip]
>
>>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.

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

Mac, May 8, 2004