Adding `int` to address causes int to be added 4 times

和自甴很熟 提交于 2019-12-25 00:38:01

问题


For a course about the functioning of operating systems, we had to write a malloc/free implementation for a specific sized struct. Our idea was to store the overhead, like the start and end of the specified (static) memory block our code has to work in, in the first few addresses of that block.

However, something went wrong with the calculation of the last memory slot; We're adding the size of all usable memory slots to the address of the first usable memory slot, to determine what the last slot is. However, when adding the int sizeofslots to the address of currentslot, it actually adds sizeofslots 4 times to this address. Here's the relevant code:

/* Example memory block*/
/* |------------------------------------------------------------------------------|*/
/* | ovr | 1 t | 0   | 1 t | 1 t | 1 t | 0   | 0   | 0   | 0   | 0   | 0   | 0   |*/
/* |------------------------------------------------------------------------------|*/
/* ovr: overhead, the variables `currentslot`, `firstslot` and `lastslot`.        
 * 1/0: Whether or not the slot is taken.      
 * t: the struct 
 */

/* Store the pointer to the last allocated slot at the first address */
currentslot = get_MEM_BLOCK_START();
*currentslot = currentslot + 3*sizeof(void *);

/* The first usable memory slot after the overhead */
firstslot = currentslot + sizeof(void *);
*firstslot = currentslot + 3*sizeof(void *);

/* The total size of all the effective memory slots */
int sizeofslots = SLOT_SIZE * numslots;

/* The last usable slot in our memory block */
lastslot = currentslot + 2*sizeof(void*);
*lastslot = firstslot + sizeofslots;
printf("%p + %i = %p, became %p\n", previous, sizeofslots, previous + (SLOT_SIZE*numslots), *lastslot);

We figured it had something to do with integers being 4 bytes, but we still don't get what is happening here; Can anyone explain it?


回答1:


When you add an integer to a pointer, it increments by that many strides (i.e. myPointer + x will increment by x*sizeof(x). If this didn't happen, it would be possible to have unaligned integers, which is many processor architectures is a fault and will cause some funky behaviour, to say the least.

Take the following as an example

char* foo = (char*)0x0; // Foo = 0
foo += 5;               // foo = 5

short* bar = (short*)0x0; // Bar = 0; (we assume two byte shorts)
bar += 5;                 // Bar = 0xA (10)

int* foobar = (int*)0x0;  // foobar = 0; (we assume four byte ints)
foobar += 2;              // foobar = 8; 

char (*myArr)[8];         // A pointer to an array of chars, 8 size
myArr += 2;               // myArr = 0x10 (16). This is because sizeof(char[8]) = 8;



回答2:


C's pointer arithmetic always works like this; addition and subtraction is always in terms of the item being pointed at, not in bytes.

Compare it to array indexing: as you might know, the expression a[i] is equivalent to *(a + i), for any pointer a and integer i. Thus, it must be the case that the addition happens in terms of the size of each element of a.

To work around it, cast the structure pointer down to (char *) before the add.




回答3:


Example

const int MAX = 3;

int main ()
{
   int  var[] = {10, 100, 200};
   int  i, *ptr;

   /* let us have array address in pointer */
   ptr = var;
   for ( i = 0; i < MAX; i++)
   {

      printf("Address of var[%d] = %x\n", i, ptr );
      printf("Value of var[%d] = %d\n", i, *ptr );

      /* move to the next location */
      ptr++;
   }
   return 0;
}

Output::

Address of var[0] = bfb7fe3c
Value of var[0] = 10
Address of var[1] = bfb7fe40
Value of var[1] = 100
Address of var[2] = bfb7fe44
Value of var[2] = 200

You can deduce from the example that, a pointer increments itself by "Number Of Bytes" = "Size of the type it is pointing to". Here it is, Number Of bytes = sizeof(int). Similarly, it will increment itself 1 byte in case of char.



来源:https://stackoverflow.com/questions/20397360/adding-int-to-address-causes-int-to-be-added-4-times

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!