CSAPP 第三版5.17习题答案

一、题目描述

在这里插入图片描述在这里插入图片描述

二、分析求解

  1. 指针长度:64位机器上所有指针类型sizeof = 8 sizeof(ptr) 与指针类型无关
  2. 指针类型:设置指针类型的目的是规定指向元素的内存大小 规定指针移动的长度 char* p p++ 移动1B int* p p++ 移动4B MyNode *p p++ 移动20B
  3. 指针类型转换测试
#include <stdio.h>

typedef struct node1{
  struct node1 *l1, *r1;
  int data;
}MyNode;

typedef struct node2{
  struct node2 *l2, *r2;
}BNode;

int main(int argc, char **args)
{
  MyNode m;
  m.l1 = (struct node1*)0x111;
  m.r1 = (struct node1*)0x222;
  m.data = 1;

  BNode *b = (BNode*)&m;
  int *p = (int*)&m;
  // 打印 0x111 0x222 1 1
  printf("%p %p %d %d\n", *p, *(p+2), *(p+4), *(int*)(b+2));
  return 0;
}
  1. 代码分析:
#include <stdio.h>

void* basic_memset(void *s, int c, size_t n) {
  size_t cnt = 0;
  unsigned char *schar = (unsigned char *)s;
  while (cnt < n) { // 按字节逐个写
    *schar++ = (unsigned char) c; 
    cnt++;
  }
  return s;
}

void* effective_memset(void *s, unsigned long cs, size_t n) {
  size_t K = sizeof(unsigned long);
  size_t cnt = 0;
  unsigned char *schar = (unsigned char *)s; // 指针类型转换
  
  while (cnt < n) {
    // printf("%p %d\n", schar, (size_t)schar);
    if ((size_t)schar % K == 0) {  // 填充字节使地址对齐为K的倍数
      break;
    }
    *schar++ = (unsigned char)cs;  // 逐字节填充
    cnt++;
  }
  
  unsigned long *slong = (unsigned long *)schar; // 指针类型转换
  size_t rest = n - cnt;
  size_t loop = rest / K;
  size_t tail = rest % K;
  for (size_t i = 0; i < loop; i++) {
    *slong++ = cs; // 按字写
  }
  
  schar = (unsigned char *)slong; // 转换指针类型
  for (size_t i = 0; i < tail; i++) {  // 填充尾部
    *schar++ = (unsigned char)cs; 
  }
  return s;
}


int main()
{
    unsigned long a = 0x6161616161616161; // "aaaaaaaa"
    int b = 0x41414141; // "AAAA"
    int *res = (int*)effective_memset(&b, a, 15);
    for (int i = 0; i < 10; i++) {
        printf("%p\n", *res++); // 打印15个0x61
    }
    return 0;
}
  1. 总结:
    第一次写15个0x61 第二次写10个0x61 内存依然保留了15个0x61 并没有删除多余的字节 而是新数据覆盖脏内存来使用内存

    写不同长度的数据关键是转换指针的类型 使指针移动不同的长度

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值