V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
oIMOo
V2EX  ›  问与答

C 语言中,没有修改数值,但数值自己变了?!

  •  
  •   oIMOo · 2019-03-14 00:05:48 +08:00 · 1352 次点击
    这是一个创建于 2087 天前的主题,其中的信息可能已经有所发展或是发生改变。

    先发出来代码,大家可以跑跑看。

    tp.h 文件:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef unsigned int Byte;
    
    typedef struct {
      int sign; /* 0 for pos and 1 for neg */
      int size;
      Byte *tab;
    } bignum;
    
    #define BASE 10
    
    #define MAX(a, b) (((a) > (b)) ? (a) : (b))
    #define MIN(a, b) (((a) < (b)) ? (a) : (b))
    
    void init(char *s, bignum *n) {
      int pos = 0;
    
      if (s[0] == '-') {
        n->sign = 1;
        n->size = strlen(s) - 1;
        // n->tab = calloc(n->size, sizeof(unsigned char));
        n->tab = (Byte *)malloc(n->size * sizeof(unsigned char));
    
        for (int i = n->size; i > 0; i--) {
          n->tab[pos] = s[i];
          pos++;
        }
      } else {
        n->sign = 0;
        n->size = strlen(s);
        // n->tab = calloc(n->size, sizeof(unsigned char));
        n->tab = (Byte *)malloc(n->size * sizeof(unsigned char));
    
        for (int i = n->size - 1; i >= 0; i--) {
          n->tab[pos] = s[i];
          pos++;
        }
      }
      // free(n->tab);
    }
    
    void showBigNum(bignum n) {
      if (n.sign == 1) {
        printf("-");
      }
      for (int i = n.size - 1; i >= 0; i--) {
        printf("%d", n.tab[i] - '0');
      }
    }
    
    
    
    tp.c 文件:
    ```C
    #include "tp2.h"
    
    int main(int argc, char *argv[]) {
      if (argc != 3) {
        printf("Please type 2 numbers as input\n");
        exit(1);
      }
    
      bignum a, b;
    
      init(argv[1], &a);
      /* You can try to comment the line below and start again, then you can see the difference */
      init(argv[2], &b);
      showBigNum(a);
    
      return 0;
    }
    
    
    可以试试:
    
    **注释掉** 和 **不注释掉** *init(argv[2], &b);* 分别输出什么。
    
    	gcc tp.c ; ./a.out 255555 122577
    
    理论上都应该输出 255555.
    
    求大佬帮助修改,并指出原因。
    
    鱼和渔都想要,不要熊掌……
    
    17 条回复    2019-03-14 01:21:35 +08:00
    111qqz
        1
    111qqz  
       2019-03-14 00:24:11 +08:00 via Android
    手机客户端排版是乱的。。。
    oIMOo
        2
    oIMOo  
    OP
       2019-03-14 00:32:12 +08:00
    @111qqz 大佬,我去看看找个网盘发上来
    CEBBCAT
        3
    CEBBCAT  
       2019-03-14 00:35:02 +08:00 via Android
    @oIMOo 这种时候 gist 是最好的

    这个问题相比你也觉得问题出在 malloc 上吧?多打几个 printf 看看嘛,对了,你编译的时候用的是什么标准?默认的?
    CEBBCAT
        4
    CEBBCAT  
       2019-03-14 00:41:04 +08:00 via Android
    oIMOo
        5
    oIMOo  
    OP
       2019-03-14 00:53:16 +08:00
    @CEBBCAT

    我发上来的是一个副本,所以删掉了一部分,谢谢提醒。
    不过这部分就是问题根源……

    我用的默认配置。

    我也试了 memset,可能方法不对……

    也试了在 init 最后 free (肯定不对,毕竟这个值我还要用),果然 free 完 a 和 b 相等了……
    geelaw
        6
    geelaw  
       2019-03-14 00:53:41 +08:00 via iPhone
    你为什么不能直接告诉我们输出了什么?你是在考试还是提问?

    无论如何,错误在于你访问越界,malloc 分配的是长度为 size 的 unsigned char 数组,但你把它当成长度为 size 的 int 数组使用。
    geelaw
        7
    geelaw  
       2019-03-14 00:55:31 +08:00 via iPhone
    @geelaw *…的 unsigned int 数组使用
    GeruzoniAnsasu
        8
    GeruzoniAnsasu  
       2019-03-14 00:55:57 +08:00
    描述只需看一句话都能肯定绝对是哪里越界了

    至于到底哪越界了可就懒得仔细查了,人肉编译器(前端)还不如你加个-fsanitize=address 或者 valgrind 跑一下
    across
        9
    across  
       2019-03-14 00:59:08 +08:00
    没跑。
    不过看到 (Byte *)malloc(n->size * sizeof(unsigned char));
    返回的是 int*指针,有对齐问题吧。n->size 不一定是 Byte*的倍数
    CEBBCAT
        10
    CEBBCAT  
       2019-03-14 01:10:29 +08:00 via Android
    看半天,我就一个问题:int 的类型为啥 malloc 的时候 sizeof 写的是无符号的 char ?

    而且 malloc 拿到的内存没有初始化吧?
    CEBBCAT
        11
    CEBBCAT  
       2019-03-14 01:12:35 +08:00 via Android
    大佬就是大佬啊,我看了好几遍才发现 malloc 那里 sizeof 用的是 unsigned char 而不是 unsigned int
    oIMOo
        12
    oIMOo  
    OP
       2019-03-14 01:14:50 +08:00
    @geelaw 见谅哈

    @geelaw @GeruzoniAnsasu @across
    按照各位的提示,将
    (Byte *)malloc(n->size * sizeof(unsigned char));
    变位
    (Byte *)malloc(n->size * sizeof(unsigned int));

    谢谢各位点拔!
    oIMOo
        13
    oIMOo  
    OP
       2019-03-14 01:15:10 +08:00
    @CEBBCAT 谢谢谢谢!
    GeruzoniAnsasu
        14
    GeruzoniAnsasu  
       2019-03-14 01:15:15 +08:00
    绝了 一般人会把 byte typedef 成 int 的吗,根本没注意到
    CEBBCAT
        15
    CEBBCAT  
       2019-03-14 01:19:15 +08:00 via Android
    @oIMOo #12 恭喜你解决了这个问题,不过该用 sizeof(Byte)嘛,这样好维护(应该?)
    oIMOo
        16
    oIMOo  
    OP
       2019-03-14 01:19:58 +08:00
    @geelaw @GeruzoniAnsasu @across @CEBBCAT @GeruzoniAnsasu

    回答一下关于类型的问题:

    因为 Byte 类型是要求,所以我先用 BASE 10 完成思路(现在正在做的)。
    然后会转到 byte 上。
    oIMOo
        17
    oIMOo  
    OP
       2019-03-14 01:21:35 +08:00
    @CEBBCAT 我去翻出看类型定义去……
    谢谢大佬。
    不然我还真发现不了自己问题……
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1214 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 18:32 · PVG 02:32 · LAX 10:32 · JFK 13:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.