【问题标题】:Adding `int` to address causes int to be added 4 times将 `int` 添加到地址会导致 int 被添加 4 次
【发布时间】:2013-12-05 10:23:54
【问题描述】:

对于有关操作系统功能的课程,我们必须为特定大小的结构编写 malloc/free 实现。我们的想法是将开销(例如我们的代码必须在其中工作的指定(静态)内存块的开始和结束)存储在该块的前几个地址中。

但是,最后一个内存槽的计算出了点问题;我们将所有可用内存插槽的大小添加到第一个可用内存插槽的地址,以确定最后一个插槽是什么。但是,当将int sizeofslots 添加到currentslot 的地址时,实际上是向该地址添加了4 次sizeofslots。以下是相关代码:

/* 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);

我们认为它与 4 字节的整数有关,但我们仍然不知道这里发生了什么;谁能解释一下?

【问题讨论】:

  • 你知道指针运算是根据指针指向的类型的大小来工作的,对吧? IE。如果您将 1 添加到 int* 您将移动到下一个 int,即 4(或 8)个字节,不是下一个字节

标签: c memory-management


【解决方案1】:

C 的指针算法总是这样工作的;加法和减法总是以所指向的项目为单位,不是以字节为单位。

将其与数组索引进行比较:您可能知道,表达式a[i] 等效于*(a + i),对于任何指针a 和整数i。因此,加法一定是根据a 的每个元素的大小发生的。

要解决此问题,请将结构指针向下转换为 (char *),然后再添加。

【讨论】:

    【解决方案2】:

    当您将整数添加到指针时,它会增加很多步幅(即myPointer + x 将增加x*sizeof(x)。如果没有发生这种情况,则可能会有未对齐的整数,这是许多处理器架构是一个错误,至少可以说会导致一些时髦的行为。

    以下面为例

    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;
    

    【讨论】:

      【解决方案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;
      }
      

      输出::

      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
      

      您可以从示例中推断出,指针自增“字节数”=“它指向的类型的大小”。在这里,字节数 = sizeof(int)。类似地,如果是 char,它将增加 1 个字节。

      【讨论】:

        猜你喜欢
        • 2020-08-28
        • 1970-01-01
        • 2010-10-09
        • 2019-10-13
        • 1970-01-01
        • 2013-05-19
        • 1970-01-01
        • 1970-01-01
        • 2015-08-16
        相关资源
        最近更新 更多