D - Dernel: pointer arithmetic question
- =?iso-8859-1?Q?Robert_M._M=FCnch?= (24/24) Mar 02 2004 Hi, I'm a bit confused how to do pointer arithmetic correctly. I have th...
- Russ Lewis (31/58) Mar 02 2004 When you add something to a pointer, it increments the pointer by the
- =?iso-8859-1?Q?Robert_M._M=FCnch?= (6/24) Mar 03 2004 Hi, ah I missed this. Is this true for C++ as well? Hmm... seems I never...
- Ilya Minkov (3/10) Mar 04 2004 Yes. "Pointer Arithmetic" is inherited from C.
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
Mar 02 2004
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.
Mar 02 2004
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.sizeHi, 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
Mar 03 2004
Robert M. M=FCnch wrote:On Tue, 02 Mar 2004 07:20:41 -0700, Russ Lewis =20 <spamhole-2001-07-16 deming-os.org> wrote: =20=20When 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=20 never used such a feature.Yes. "Pointer Arithmetic" is inherited from C.
Mar 04 2004