在 C 中从一个地址中减去另一个地址



在家庭作业项目中,我必须从一个指针中减去另一个指针的地址。这是我尝试编写的一段代码,用于从给定的元数据地址中减去 void* 类型的堆。某处是错误的。

metadata_t* getBuddy(metadata_t* ptr)
{
 metadata_t* offset = ptr - (char)heap;
 int h = (char)heap;
#ifdef DEBUG
 printf("ptr : %pn", ptr);
 printf("heap : %pn", heap);
 printf("offset: %pn", offset);
 printf("char : %dn", h);
 #endif
    return NULL;
}

这是我得到的输出:

ptr   : 0x7fe7b3802440 
heap  : 0x7fe7b3802200 
offset: 0x7fe7b3802440 
char  : 0

这是我期望的输出:

ptr   : 0x7fe7b3802440 
heap  : 0x7fe7b3802200 
offset: 0x000000000240 
char  : 0x7fe7b3802200 

问题:

1) 为什么字符输出为零?(这不是我正在做的吗:将 a 指针转换为单个字节,然后将其存储到 int 中)

2)如果这不是您正确进行指针算术的方式,那么您将如何完成偏移?

编辑:

1)我认为堆被定义为int*。这是返回其值的给定代码段。

#define HEAP_SIZE 0x2000
void *my_sbrk(int increment) {
  static char *fake_heap = NULL;
  static int current_top_of_heap = 0;
  void *ret_val;
  if(fake_heap == NULL){
    if((fake_heap = calloc(HEAP_SIZE, 1)) == NULL) {
      return (void*)-1;
    }
  }
  ret_val=current_top_of_heap+fake_heap;
  if ((current_top_of_heap + increment > HEAP_SIZE) 
      || (current_top_of_heap+increment < 0)) {
    errno=ENOMEM;
    return (void*)-1;
  }
  current_top_of_heap += increment;
  return ret_val;
}

指针算术只对特定类型有意义。在此示例中,int 类型的大小为 4,但指针减法仅为 1。

#include <stdio.h>
int array[2];
int *a, *b;
int main(void){
    a = &array [0];
    b = &array [1];
    printf ("Int size = %dn", sizeof(int));
    printf ("Pointer difference = %dn", b-a);
    return 0;
}

程序输出:

Int size = 4
Pointer difference = 1

指针算术不支持该操作(指针+指针)。唯一允许的操作是(指针 + 整数),因此结果是指针。

若要获取偏移量,需要将两个指针强制转换为整数类型。结果值是整数而不是指针。

例:

int offset = (int)ptr - (int)heap;
printf("ptr : %pn", ptr);
printf("heap : %pn", heap);
printf("offset: %dn", offset);

此外,heap的值太大而无法存储在单个字节中,这就是为什么将其转换为char类型返回值零的原因。

相关内容

  • 没有找到相关文章

最新更新