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

2019-03-14 00:05:48 +08:00
 oIMOo

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

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.

求大佬帮助修改,并指出原因。

鱼和渔都想要,不要熊掌……
1348 次点击
所在节点    问与答
17 条回复
111qqz
2019-03-14 00:24:11 +08:00
手机客户端排版是乱的。。。
oIMOo
2019-03-14 00:32:12 +08:00
@111qqz 大佬,我去看看找个网盘发上来
CEBBCAT
2019-03-14 00:35:02 +08:00
@oIMOo 这种时候 gist 是最好的

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

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

我用的默认配置。

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

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

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

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

而且 malloc 拿到的内存没有初始化吧?
CEBBCAT
2019-03-14 01:12:35 +08:00
大佬就是大佬啊,我看了好几遍才发现 malloc 那里 sizeof 用的是 unsigned char 而不是 unsigned int
oIMOo
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
2019-03-14 01:15:10 +08:00
@CEBBCAT 谢谢谢谢!
GeruzoniAnsasu
2019-03-14 01:15:15 +08:00
绝了 一般人会把 byte typedef 成 int 的吗,根本没注意到
CEBBCAT
2019-03-14 01:19:15 +08:00
@oIMOo #12 恭喜你解决了这个问题,不过该用 sizeof(Byte)嘛,这样好维护(应该?)
oIMOo
2019-03-14 01:19:58 +08:00
@geelaw @GeruzoniAnsasu @across @CEBBCAT @GeruzoniAnsasu

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

因为 Byte 类型是要求,所以我先用 BASE 10 完成思路(现在正在做的)。
然后会转到 byte 上。
oIMOo
2019-03-14 01:21:35 +08:00
@CEBBCAT 我去翻出看类型定义去……
谢谢大佬。
不然我还真发现不了自己问题……

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/544348

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX