Thread overview | ||||||
---|---|---|---|---|---|---|
|
March 02, 2004 Dernel: pointer arithmetic question | ||||
---|---|---|---|---|
| ||||
Hi, I'm a bit confused how to do pointer arithmetic correctly. I have the following code:
struct memory_map {
uint entry_size;
uint base_addr_low;
uint base_addr_high;
uint length_low;
uint length_high;
uint type;
}
Than I have a loop:
for(memory_map *mem_map = (memory_map*)mbi.mmap_addr;
(uint) mem_map <= (uint)(mbi.mmap_addr + mbi.mmap_length);
mem_map = (mem_map + mem_map.entry_size + mem_map.entry_size.sizeof)) {
The last line is the problem: mem_map is set to something way off in memory. If I change the line to:
mem_map = (memory_map*)((uint)mem_map + mem_map.entry_size + mem_map.entry_size.sizeof);
it works. So, why do I need to use explicit casts? What does D do, if I don't convert mem_map to uint but still add some stuff.
--
Robert M. Münch
Management & IT Freelancer
http://www.robertmuench.de
|
March 02, 2004 Re: Dernel: pointer arithmetic question | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert M. Münch | When you add something to a pointer, it increments the pointer by the size of the type. So, for example: byte *foo = (byte*)0x1000; foo++; // foo now equals 0x1001 uint *bar = (uint*)0x1000; bar++; // bar now equals 0x1004, since uint.size == 4 MyStruct *baz = (MyStruct*)0x1000; baz++; // baz now equals 0x1000+MyStruct.size (Unless your pointer is a (byte*)) you should NEVER do this: ptr_variable + <somethingElse>.sizeof since sizeof returns the size in bytes but when you add you are adding in terms of the size of the thing the pointer points to! The reason your 2nd code worked is because you cast the pointer to a uint, did the arithmetic by hand, and then cast back to a pointer. Ordinarily, when you have an array of structs, you can just use ordinary pointer arithmetic...just make sure that the things you add (or subtract) are the number of structs you want to increment, not the number of bytes. But if you need to do byte arithmetic, my preferred way is to cast things to (byte*): MyStruct *foo; foo = (MyStruct*)(((byte*)base_pointer) + offset_in_bytes); * So you first cast your pointer to a (byte*) * Then you do pointer arithmetic...but since the size of 'byte' is 1, you are offsetting in terms of bytes * Then you cast back to your desired pointer type. (I think that) this should produce the exact same assembly language as if you cast the pointer to a (uint), but this is easier to read. See also http://digitalmars.com/d/expression.html. Read the section on "Add Expressions." Russ Robert M. Münch wrote: > Hi, I'm a bit confused how to do pointer arithmetic correctly. I have the following code: > > struct memory_map { > uint entry_size; > uint base_addr_low; > uint base_addr_high; > uint length_low; > uint length_high; > uint type; > } > > Than I have a loop: > > for(memory_map *mem_map = (memory_map*)mbi.mmap_addr; > (uint) mem_map <= (uint)(mbi.mmap_addr + mbi.mmap_length); > mem_map = (mem_map + mem_map.entry_size + mem_map.entry_size.sizeof)) { > > The last line is the problem: mem_map is set to something way off in memory. If I change the line to: > > mem_map = (memory_map*)((uint)mem_map + mem_map.entry_size + mem_map.entry_size.sizeof); > > it works. So, why do I need to use explicit casts? What does D do, if I don't convert mem_map to uint but still add some stuff. > |
March 04, 2004 Re: Dernel: pointer arithmetic question | ||||
---|---|---|---|---|
| ||||
Posted in reply to Russ Lewis | On Tue, 02 Mar 2004 07:20:41 -0700, Russ Lewis <spamhole-2001-07-16@deming-os.org> wrote: > When you add something to a pointer, it increments the pointer by the size of the type. So, for example: > > byte *foo = (byte*)0x1000; > foo++; // foo now equals 0x1001 > uint *bar = (uint*)0x1000; > bar++; // bar now equals 0x1004, since uint.size == 4 > MyStruct *baz = (MyStruct*)0x1000; > baz++; // baz now equals 0x1000+MyStruct.size Hi, ah I missed this. Is this true for C++ as well? Hmm... seems I never used such a feature. > The reason your 2nd code worked is because you cast the pointer to a uint, did the arithmetic by hand, and then cast back to a pointer. Of course now it makes sense. > But if you need to do byte arithmetic, my preferred way is to cast things to (byte*): > > MyStruct *foo; > foo = (MyStruct*)(((byte*)base_pointer) + offset_in_bytes); > > * So you first cast your pointer to a (byte*) > * Then you do pointer arithmetic...but since the size of 'byte' is 1, you are offsetting in terms of bytes > * Then you cast back to your desired pointer type. Yes, good point. Thanks a lot. Robert |
March 04, 2004 Re: Dernel: pointer arithmetic question | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert M. Münch | Robert M. Münch wrote: > On Tue, 02 Mar 2004 07:20:41 -0700, Russ Lewis <spamhole-2001-07-16@deming-os.org> wrote: > >> When you add something to a pointer, it increments the pointer by the size of the type. So, for example: > Hi, ah I missed this. Is this true for C++ as well? Hmm... seems I never used such a feature. Yes. "Pointer Arithmetic" is inherited from C. |
Copyright © 1999-2021 by the D Language Foundation