鱼C论坛

 找回密码
 立即注册
查看: 1494|回复: 4

[已解决]s1e39动动手0

[复制链接]
发表于 2023-6-12 22:03:07 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
// malloc 和 realloc 函数创建一个可以存放任意长度整数的容器(数字以字符的形式存储),想问一下第二个if语句啥意思,以及为啥用了malloc和realloc不用free释放(是没必要吗),如果能用怎样改进程序?
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. #define INCREMENT 10
  4. #define INIT_SIZE INCREMENT

  5. int main(void)
  6. {
  7.         char ch;
  8.         char *num; // 存储整个数据的首地址
  9.         char *last; // 最近一次迭代的起始地址
  10.         int limit = 0; // 每次迭代的限制值
  11.         long times = 1; // 记录重新申请多少次内存

  12.         num = (char *)malloc(INIT_SIZE);
  13.         if (num == NULL)
  14.         {
  15.                 exit(1);
  16.         }

  17.         last = num;

  18.         printf("请输入一个整数:");

  19.         while ((ch=getchar()) != '\n')
  20.         {
  21.                 last[limit++] = ch;
  22.                 if (limit >= INCREMENT)
  23.                 {
  24.                         int offset = last - num;
  25.                         num = (char *)realloc(num, INIT_SIZE + INCREMENT * times++);
  26.                         last = num;
  27.                         last += offset;
  28.                         last += INCREMENT;
  29.                         limit = 0;
  30.                 }
  31.         }
  32.         last[limit] = '\0';

  33.         printf("你输入的整数是:%s\n", num);

  34.         return 0;
  35. }
复制代码
最佳答案
2023-6-12 22:14:28
这段代码读取用户输入的一个整数,整数的长度没有限制,它可以足够长。整数的每个字符都存储在动态分配的内存中。

第二个 if 语句检查是否已经填满了当前分配的内存。如果已经填满了,就通过 realloc 函数扩大内存容量。在扩大之后,这个内存的地址可能会改变,所以需要更新 num 和 last 的值。代码还保持了一个偏移量 offset,当内存移动后,以保证 last 指向正确的位置。

至于为什么代码中没有使用 free 函数来释放内存,这是因为在程序结束时,操作系统会自动回收所有的进程内存。在这个程序中,动态分配的内存会在程序结束后被操作系统自动回收,所以不需要显式地调用 free。然而,如果你的程序是一个长期运行的程序,或者在运行期间动态分配了大量的内存,你应该在不再需要内存的时候释放它,以避免内存泄漏。

可以改进这个程序,在程序结束之前,通过调用 free 函数来释放动态分配的内存。这个改进版本的程序如下:

  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. #define INCREMENT 10
  4. #define INIT_SIZE INCREMENT

  5. int main(void)
  6. {
  7.         char ch;
  8.         char *num; // 存储整个数据的首地址
  9.         char *last; // 最近一次迭代的起始地址
  10.         int limit = 0; // 每次迭代的限制值
  11.         long times = 1; // 记录重新申请多少次内存

  12.         num = (char *)malloc(INIT_SIZE);
  13.         if (num == NULL)
  14.         {
  15.                 exit(1);
  16.         }

  17.         last = num;

  18.         printf("请输入一个整数:");

  19.         while ((ch=getchar()) != '\n')
  20.         {
  21.                 last[limit++] = ch;
  22.                 if (limit >= INCREMENT)
  23.                 {
  24.                         int offset = last - num;
  25.                         num = (char *)realloc(num, INIT_SIZE + INCREMENT * times++);
  26.                         if (num == NULL)
  27.                         {
  28.                                 exit(1);
  29.                         }
  30.                         last = num + offset;
  31.                         limit = 0;
  32.                 }
  33.         }
  34.         last[limit] = '\0';

  35.         printf("你输入的整数是:%s\n", num);

  36.         // 释放动态分配的内存
  37.         free(num);

  38.         return 0;
  39. }
复制代码


这个改进版本的程序在程序结束之前,释放了动态分配的内存。在代码中,如果 realloc 函数返回 NULL,表明内存分配失败,程序会立即退出。如果内存分配成功,程序会继续执行,并在结束时释放动态分配的内存。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-6-12 22:14:28 | 显示全部楼层    本楼为最佳答案   

回帖奖励 +5 鱼币

这段代码读取用户输入的一个整数,整数的长度没有限制,它可以足够长。整数的每个字符都存储在动态分配的内存中。

第二个 if 语句检查是否已经填满了当前分配的内存。如果已经填满了,就通过 realloc 函数扩大内存容量。在扩大之后,这个内存的地址可能会改变,所以需要更新 num 和 last 的值。代码还保持了一个偏移量 offset,当内存移动后,以保证 last 指向正确的位置。

至于为什么代码中没有使用 free 函数来释放内存,这是因为在程序结束时,操作系统会自动回收所有的进程内存。在这个程序中,动态分配的内存会在程序结束后被操作系统自动回收,所以不需要显式地调用 free。然而,如果你的程序是一个长期运行的程序,或者在运行期间动态分配了大量的内存,你应该在不再需要内存的时候释放它,以避免内存泄漏。

可以改进这个程序,在程序结束之前,通过调用 free 函数来释放动态分配的内存。这个改进版本的程序如下:

  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. #define INCREMENT 10
  4. #define INIT_SIZE INCREMENT

  5. int main(void)
  6. {
  7.         char ch;
  8.         char *num; // 存储整个数据的首地址
  9.         char *last; // 最近一次迭代的起始地址
  10.         int limit = 0; // 每次迭代的限制值
  11.         long times = 1; // 记录重新申请多少次内存

  12.         num = (char *)malloc(INIT_SIZE);
  13.         if (num == NULL)
  14.         {
  15.                 exit(1);
  16.         }

  17.         last = num;

  18.         printf("请输入一个整数:");

  19.         while ((ch=getchar()) != '\n')
  20.         {
  21.                 last[limit++] = ch;
  22.                 if (limit >= INCREMENT)
  23.                 {
  24.                         int offset = last - num;
  25.                         num = (char *)realloc(num, INIT_SIZE + INCREMENT * times++);
  26.                         if (num == NULL)
  27.                         {
  28.                                 exit(1);
  29.                         }
  30.                         last = num + offset;
  31.                         limit = 0;
  32.                 }
  33.         }
  34.         last[limit] = '\0';

  35.         printf("你输入的整数是:%s\n", num);

  36.         // 释放动态分配的内存
  37.         free(num);

  38.         return 0;
  39. }
复制代码


这个改进版本的程序在程序结束之前,释放了动态分配的内存。在代码中,如果 realloc 函数返回 NULL,表明内存分配失败,程序会立即退出。如果内存分配成功,程序会继续执行,并在结束时释放动态分配的内存。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-6-12 22:20:16 | 显示全部楼层
本帖最后由 houqing1999 于 2023-6-12 22:21 编辑
isdkz 发表于 2023-6-12 22:14
这段代码读取用户输入的一个整数,整数的长度没有限制,它可以足够长。整数的每个字符都存储在动态分配的内 ...


c(31,31): warning C4244: “初始化”: 从“__int64”转换到“int”,可能丢失数据

程序可以运行但给到一个这样的警告

而且输入的哪怕不是整数也能输出,这个是程序问题吗
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-6-12 22:24:10 | 显示全部楼层
houqing1999 发表于 2023-6-12 22:20
c(31,31): warning C4244: “初始化”: 从“__int64”转换到“int”,可能丢失数据

程序可以运行但 ...

关于你的第一个问题,警告  C4244: “初始化”: 从“__int64”转换到“int”,可能丢失数据  是因为你在代码中使用的  long  类型的  times  变量,在进行乘法操作  INCREMENT * times++  时,结果可能超出  int  的范围。在64位操作系统中, long  类型的长度为64位(即  __int64 ),而  int  类型的长度为32位。当你将一个  long  类型赋值给一个  int  类型时,如果  long  类型的值超过了  int  类型的最大值,那么将会丢失数据。

你可以通过改变  times  的类型为  int  或者其他方式来解决这个问题,但是需要注意,如果你将  times  类型改为  int ,在输入的整数长度超过  INT_MAX / INCREMENT  时,程序可能会发生未定义的行为。

关于你的第二个问题,程序本身是按字符来接收用户的输入的,然后将这些字符以字符串的形式输出,所以不论输入的是整数、小数还是非数字字符,程序都能接收并输出。如果你希望程序只接收整数,那么你需要在代码中加入检查机制,只接收整数输入。这样的需求一般需要更复杂的错误处理或者字符串解析技术,是在这个代码之外的话题。

总的来说,这个程序的主要目的是演示如何使用  malloc  和  realloc  函数动态地调整内存的大小,以适应不定长度的输入,而不是解析输入的数值。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-6-12 22:24:10 | 显示全部楼层

回帖奖励 +5 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-10 02:24

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表