brk()和sbrk()的简单练习

本文介绍了一个简单的通讯录小程序的功能实现,包括添加、查找、删除联系人及文件保存与导入功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


 

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <fcntl.h>
  5. #include <errno.h>
  6. struct User{
  7.  char name[20];
  8.  int telnum;
  9. };
  10. static struct User* UserList;
  11. struct User* Now;
  12.  void
  13. showUser(struct User u)
  14. {
  15.  printf("姓名:%s --- 号码:%d\n",u.name,u.telnum);
  16. }
  17.  struct User
  18. addUser()
  19. {
  20.  Now = sbrk(0);
  21.  Now = sbrk(sizeof(struct User));
  22.  printf("输入添加用户名\n");
  23.  scanf("%s",Now->name);
  24.  printf("输入号码\n");
  25.  scanf("%d",&(Now->telnum));
  26.  printf("添加成功\n");
  27.  return *Now;
  28. }

  29. struct User*
  30. find(const char* name)
  31. {
  32.  struct User* p = UserList;
  33.  struct User* end = sbrk(0);
  34.  for(;p!=end;p++)
  35.  {
  36.   if(!strcmp(name,p->name)) {
  37.    printf("已找到\n"
  38.      "姓名:%s --- 号码:%d\n",p->name,p->telnum);
  39.    return p;
  40.   }
  41.  }
  42.  printf("未找到\n");
  43.  return NULL;
  44. }
  45. void
  46. selectByName()
  47. {
  48.  printf("输入要查找的姓名\n");
  49.  char name[20];
  50.  scanf("%s",name);
  51.  find(name);
  52.  return ;
  53. }
  54.  void
  55. delUser()
  56. {
  57.  printf("输入要删除的姓名:\n");
  58.  char name[20];
  59.  scanf("%s",name);
  60.  struct User *p = find(name);
  61.  if(p==NULL){
  62.   return;
  63.  }else{
  64.   //*p = (struct User)NULL;
  65.   p->name[0] = '\0';
  66.   printf("删除成功\n");
  67.   return;
  68.  }
  69. }
  70.  void
  71. saveFile()
  72. {
  73.  umask(0022);
  74.  int fd = open("USER.DAT",O_RDWR|O_CREAT|O_TRUNC,0666);
  75.  if(fd==-1){
  76.   perror("FILE NO EXCT");
  77.   return;
  78.  }
  79.  struct User* p = UserList;
  80.  struct User* end = sbrk(0);
  81.  for(;p!=end;p++)
  82.  {
  83.   if(p->name[0]!='\0')
  84.    pwrite(fd,p,sizeof(struct User),lseek(fd,0,SEEK_END));
  85.  }
  86.  printf("文件储存完成\n");
  87.  close(fd);
  88.  return;
  89. }
  90.  void
  91. showAll()
  92. {
  93.  struct User* p = UserList;
  94.  struct User* end = sbrk(0);
  95.  for(;p!=end;p++)
  96.  {
  97.   if(p->name[0]!='\0')
  98.    showUser(*p);
  99.  }
  100.  return;
  101. }
  102. void
  103. loadFromFile()
  104. {
  105.  char file[50];
  106.  printf("输入文件路径\n");
  107.  scanf("%s",file);
  108.  int fd = open(file,O_RDONLY);
  109.  if(fd==-1){
  110.   printf("file error\n");
  111.   loadFromFile();
  112.  }
  113.  off_t beg = lseek(fd,0,SEEK_SET);
  114.  off_t end = lseek(fd,0,SEEK_END);
  115.  off_t size = end - beg;
  116.  lseek(fd,0,SEEK_SET);
  117.  read(fd,UserList,size);

  118.  printf("load success!!!\n");
  119.  return ;
  120. }
  121.  int
  122. main()
  123. {
  124.  UserList = sbrk(0);
  125.  Now = sbrk(0);
  126.  int fd = open("USER.DAT",O_RDONLY);
  127.  if(fd==-1){
  128.   printf("file error\n");
  129.   return -1;
  130.  }
  131.  lseek(fd,0,SEEK_SET);
  132.  read(fd,(struct User*)UserList,end-beg);
  133.  close(fd);
  134.  printf("*************************************************\n"
  135.    "通讯录小程序\n"
  136.    "*************************************************\n"
  137.    "[1]显示所有记录\n"
  138.    "[2]添加记录\n"
  139.    "[3]查找记录\n"
  140.    "[4]删除记录\n"
  141.    "[5]文件保存\n"
  142.    "[6]导入文件记录\n"
  143.    "[0]退出\n");
  144.  while(1)
  145.  {
  146.   printf("请选择\n");
  147.   int num = 0;
  148.   scanf("%d",&num);
  149.   switch(num){
  150.    case 1:showAll();break;
  151.    case 2:addUser();break;
  152.    case 3:selectByName();break;
  153.    case 4:delUser();break;
  154.    case 5:saveFile();break;
  155.    case 6:printf("导入文件记录\n");break;
  156.    case 0:saveFile();brk(UserList);exit(0);
  157.   }
  158.  }
  159. }


 

<script>window._bd_share_config={"common":{"bdsnskey":{},"bdtext":"","bdmini":"2","bdminilist":false,"bdpic":"","bdstyle":"0","bdsize":"16"},"share":{}};with(document)0[(getelementsbytagname('head')[0]||body).appendchild(createelement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new date()/36e5)];</script>
阅读(180) | 评论(0) | 转发(0) |
0

上一篇:几种排序算法

下一篇:信号知识简单梳理

给主人留下些什么吧!~~
评论热议
### brk sbrk 系统调用的区别及在内存管理中的作用 #### 1. 定义与功能 `brk` `sbrk` 是两个用于调整进程堆大小的系统调用。`brk` 直接指定新的程序中断位置(program break),而 `sbrk` 则通过增量来调整当前的程序中断位置[^3]。 - **`brk`**:接受一个指针作为参数,直接将程序中断设置到该地址。如果成功,返回值为 0;否则返回 -1 并设置 `errno` 为 `ENOMEM`。 - **`sbrk`**:接受一个整数增量作为参数,表示相对于当前程序中断的偏移量。如果增量为正,则增加堆的大小;如果为负,则减少堆的大小。返回值是调整前的程序中断地址[^3]。 #### 2. 参数与返回值 - **`brk` 的参数**是一个指向新程序中断位置的指针。它不返回旧的程序中断位置,仅返回操作是否成功。 - **`sbrk` 的参数**是一个整数值,表示相对于当前程序中断的增量。返回值是调整前的程序中断地址,这使得 `sbrk` 更适合用于动态内存分配场景[^3]。 #### 3. 使用场景 通常情况下,`sbrk` 被用来分配内存,而 `brk` 被用来释放内存。例如,可以通过以下方式使用 `brk` 来释放由 `sbrk` 分配的内存: ```c void *old = sbrk(0); // 获取当前程序中断位置 void *p = sbrk(MAX * MAX); // 分配内存 int err = brk(old); // 回收内存至原始位置 if (-1 == err) { perror("brk"); exit(EXIT_FAILURE); } ``` 这种方式比使用 `sbrk(-MAX*MAX)` 更加清晰直观[^1]。 #### 4. 内存管理中的作用 `brk` `sbrk` 都用于调整堆的大小,从而实现内存的动态分配释放。然而,现代内存分配器(如 `malloc` `free`)很少直接使用这些系统调用,而是通过更复杂的机制(如 `mmap` `munmap`)来管理内存,以提高效率灵活性[^2]。 #### 5. 示例代码 以下是一个简单的例子,展示如何使用 `brk` `sbrk` 来调整堆的大小: ```c #include <unistd.h> #include <stdio.h> #include <stdlib.h> int main() { void *old_brk = sbrk(0); // 获取当前程序中断位置 printf("Initial program break: %p\n", old_brk); void *new_brk = sbrk(4096); // 增加堆大小 4KB if (new_brk == (void *)-1) { perror("sbrk"); exit(EXIT_FAILURE); } printf("New program break: %p\n", new_brk); int err = brk(old_brk); // 恢复到原来的程序中断位置 if (err == -1) { perror("brk"); exit(EXIT_FAILURE); } printf("Program break restored to: %p\n", old_brk); return 0; } ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值