【问题标题】:Weird issue with mallocmalloc 的奇怪问题
【发布时间】:2018-06-26 21:35:37
【问题描述】:

我正在做一个简单的代码来打开一个带有矩阵的文件,但我遇到了一个奇怪的错误。这是我的代码:

char** CM;
char** ACM;
int lines, columns;
int i, j;

//read file
FILE* file = fopen("matrix.txt", "r");
fscanf(file, "%i %i", &lines, &columns);
CM = (char**)malloc(sizeof(char)*lines);
ACM = (char**)malloc(sizeof(char)*lines);
for(i=0; i<lines; i++)
{
    CM[i] = (char*)malloc(sizeof(char)*columns+1);
    ACM[i] = (char*)malloc(sizeof(char)*columns);
    fscanf(file, "%s", CM[i]);
    CM[i] = (char*)realloc(CM[i], sizeof(char)*columns);//don't need \n
    printf("%s\n", CM[i]);
}
printf("\n");
for(i=0; i<lines; i++)
{
    printf("%s\n", CM[i]);
}

但是输出结果却不是我所期望的:

00000
01010
01010
01100
00000

��6
01010
01010
01100
00000

如果我评论ACM[i] = (char*)malloc(sizeof(char)*columns);,它可以正常工作。我什至使用 GDB 来查看发生了什么,我得到了这个:

23          ACM[i] = (char*)malloc(sizeof(char)*columns);
2: CM[0][0] = 48 '0'
3: CM[1][1] = 49 '1'
4: i = 4
(gdb) 
24          fscanf(file, "%s", CM[i]);
2: CM[0][0] = -80 '\260'
3: CM[1][1] = 49 '1'
4: i = 4

请问,有人能告诉我我的代码发生了什么吗?

【问题讨论】:

  • 您使用的是 C 还是 C++?如果是后者,您不应该使用malloc。
  • 又一个可以通过在 malloc 中不使用 sizeof(type) 来修复的错误
  • 这个问题肯定有几十个重复。有链接@M.M?
  • 我正在编写一个简单的代码 -- 如果你使用 std::string 和/或 std::vector 而不是原始指针,会简单得多。
  • @PaulMcKenzie 但是否是c++ 尚无定论。不幸的是,代码中没有指标。

标签: c++ c memory malloc


【解决方案1】:

malloc(sizeof(char)*lines) 分配足够的内存来容纳line 数量的chars。您需要足够的内存来保存line 数量的char*s。因此,您需要使用sizeof(char*) 而不是sizeof(char)。

CM = (char**)malloc(sizeof(char*)*lines);
ACM = (char**)malloc(sizeof(char*)*lines);

作为良好的编码习惯,请使用:

CM = (char**)malloc(sizeof(*CM)*lines);    // CM  -> sizeof(*CM)
ACM = (char**)malloc(sizeof(*ACM)*lines);  // ACM -> sizeof(*ACM)

这样可以防止您遇到的那种错误。

【讨论】:

  • @RafaelMarinho,sizeof 的参数可以是类型或表达式。当它是一个表达式时,它的类型用于得出大小。当您使用*CM 作为sizeof 的参数时,tit 的计算结果为char* 类型的表达式,这正是您所需要的。
【解决方案2】:

在

ACM = (char**)malloc(sizeof(char)*lines);

您分配的是行字符,而不是行字符 * s

【讨论】:

    【解决方案3】:

    使用char **CM = (char**)malloc(sizeof(char)*lines) 和char **ACM = (char**)malloc(sizeof(char)*lines),您分配一个字符序列,但您应该分配一个指针列表。

    改写char **CM = (char**)malloc(sizeof(char*)*lines) 和char **ACM = (char**)malloc(sizeof(char*)*lines)。

    作为一般规则,返回类型(在您的情况下为char**)通常比malloc 中的类型多一个星号,即(在您的情况下为char*)。

    进一步注意,在 C 中你通常不强制转换 malloc 的结果,而在 C++ 中你必须强制转换。顺便说一句:malloc 在 C++ 中很少使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-05
      • 2011-01-21
      • 1970-01-01
      • 1970-01-01
      • 2023-02-02
      • 1970-01-01
      相关资源
      最近更新 更多