Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I could nitpick, and say "You didn't give us enough information". Technically this is true, but it just requires making some assumptions. <code>u8</code> and <code>u32</code> aren't standard C types, and you could have them typedefed to anything, but presumably, they represent an unsigned 8 bit value (e.g. <code>uchar</code>) and an unsigned 32 bit value (e.g. <code>unsigned</code>). Assuming that, let's look at the ones you understand, and explain where that leaves the third one.</p> <p>BufferPointer is a const u8*, which means it's a constant pointer of type u8. That means the array it's pointing to is of type 8-bit unsigned.</p> <p>Now, <code>BufferAddress</code> is a u32 - that's typical for pointers, at least on a 32 bit system. Since they're always the size of the bus, on a 64bit system, pointers are 64 bits.</p> <p>So, Method1 is printing the elements of the array and the address of the array. That's fine and cool.</p> <p>Method2:</p> <p>*(u8 *)(BufferAddress+i), BufferAddress+i</p> <p>BufferAddress is an unsigned integer, and you're adding values to it to get the other addresses. That's a basic point of arrays - the memory will be contiguous, and you access the next element by advancing the number of bytes of each element. Since it's a u8 array, you just advance by 1. Here's a catch, though - if it was an array of ints, you'd want BufferAddress+(i*4), not BufferAddress+i, because the size of each int is 4 bytes. Incidentally, this is how pointer arithmetic works in C. If you did `&amp;(((u32 *)BufferAddress) + 1) you'd get 0x100004 instead of 0x100001, because you casted BufferAddress to a 4byte pointer, and the compiler knows that when you're looking at the next element, it has to be 4 bytes away.</p> <p>So <code>(BufferAddress+i)</code> is the address of the ith element of the u8 array. The <code>(u8 *)</code> casts BufferAddress from a boring integer to a pointer to memory locations of type u8, so that when you do <code>*(u8 *)</code>, the compiler knows to treat it as a u8. You could do <code>(u64 *)</code>, and the compiler would say "Oh! This area of memory is 64 bit", and attempt to interpret the values in that way.</p> <p>Which might make it clear what's happening in Method 3 now. You're getting the appropriate addresses of each array element, but you're telling the compiler "treat this area of memory as 32 bit data". So each time you use *(u32 *), you're reading 4 bytes of the array and treating it as an unsigned int. Incidentally, once i >= 3, you're hitting undefined behavior, because you're reading outside of the array.</p> <p>Let me try to give a visualization of what your memory in that area looks like:</p> <pre><code>0x1000000 = 1 0x1000001 = 0 0x1000002 = 0 0x1000003 = 4 0x1000004 = 0 0x1000005 = 0 </code></pre> <p>For method2, when i = 2, you're looking at BufferAddress (=0x1000000) + 3, i.e. 0x1000002, which has the number 0 in it. The compiler knows it's only one byte, so goes with that.</p> <p>But for method3, when i = 3, you're telling the compiler to treat it as 32 bits. So it doesn't see '0', it see 0, 4, 0, 0, and uses these numbers to come up with an integer value, which will definitely not be 4.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload