【问题标题】:Storing a char in an array segfault将字符存储在数组段错误中
【发布时间】:2013-04-10 14:38:51
【问题描述】:

我的代码中出现了段错误,我不知道为什么。我通读一个文件并计算行数,以便动态分配我的数组。然后我倒带文件,读取文件中的数据,将数据存储到变量中,然后将读取的变量存储到数组中,但是我遇到了字符问题。

   ...
   char *aname = malloc(sizeof(char) * 3); 
   ... 
   // get # lines in file (count)
   ... 
   char *aname_seen = malloc(count * (sizeof(char) * 3));
   ...
   rewind(file);
   while (fgets(buff, sizeof buff, file) != NULL) 
   {
      if (sscanf(buff, "%s %d %s %s %d %lf %lf %lf %lf %lf\n", 
         atm, &serial, aname, resName, &resSeq, &x, &y, &z, 
         &occupancy, &tempFactor) == 10)
      {
         aname_seen[i] = *aname;
         printf("%d: %s vs %s\n", i, aname, aname_seen[i]);

         i++;

      } // end sscanf if-loop

   } // end while loop

我可以使用printf("%d: %s\n", i, aname) 打印名称并获得预期的输出,但是当我尝试printf("%d: %s vs %s\n", i, aname, aname_seen[i]) 时却得到Segmentation fault (core dumped)

这个 while 循环 + 嵌套 if 循环与我用来计算行数的约定相同,因此i 将递增到计数。我是否错误地分配了 aname_seen 而实际上没有给它 count 数量的 char*3 元素?我不太擅长弄乱char。更多的是数字 fortran 爱好者,所以我需要一些指导。

提前致谢!

【问题讨论】:

  • 建议通过sscanf() 指定分配给字符串的最大字符数来防止潜在的缓冲区溢出。这可以通过将"%s" 格式说明符替换为"%Ns" 来完成,其中N 比正在填充的数组中的字符数少一。
  • 您似乎没有初始化i。刚刚被忽略了吗?
  • 你知道aname_seen[i] = *aname; 只复制一个字符吗?
  • @interjay,我现在意识到了这一点。我询问了如何在可修改的左值的答案上解决这个问题。如果您有解决方案,将不胜感激!
  • @Chowlett,它已经被初始化了,只是没有显示在这个sn-p中。

标签: c char segmentation-fault


【解决方案1】:

%s 格式说明符应该对应于 char * 参数。在您的情况下,aname_seen[i]char,它被提升为 int 以传递给可变参数函数 (printf)。 int 不是 char *

也许您的意思是其中之一:

printf("%d: %s vs %c\n", i, aname, aname_seen[i]);
printf("%d: %s vs %s\n", i, aname, &aname_seen[i]);

如果这些都不能解决你的问题,请准确解释你期望从这个表达式中得到的行为,并给我们一个最小的、可编译的测试用例。您当前的测试用例不可编译。

【讨论】:

  • 这解决了打印输出问题,但又出现了另一个问题。其中一些名称是 HA、CA 等,但 aname_seen 仅存储这些字符串的第一个字符。有没有办法修改 aname_seen 以便它可以存储 aname 包含的全部内容?
  • 确实有一种方法可以修改 aname_seen 以便它可以存储 aname 包含的全部内容。我敢肯定,您正在阅读的这本书很早就涵盖了这个主题。
  • 我在读的书?这是工业药品生产代码。
  • 不幸的是,您无法通过反复试验或无指导的示例(修改复制/粘贴的代码)来学习 C。 C 有一个被称为“未定义行为”的概念,这是不可取的。未定义行为的一个示例是您的问题主题:导致您的段错误的代码。但是,不需要段错误。调用未定义行为的程序似乎可以在某些系统上运行,但这只是巧合。在其他系统上,这样的程序可能会以微妙或破坏性的方式出现故障(例如产生段错误)。为了避免未定义的行为,您需要从书中学习 C。
  • @mjswartz 你已经证明char c; 中的c 类型和char *p; 中的p 类型之间存在混淆。 * 很重要,因为它表示一个指针。一本书将详细解释差异,以及用于复制字符串的标准 C 函数 (strcpy)。我建议 K&Rs “The C Programming Language”,第二版。
【解决方案2】:

你定义 aname_seen 的方式是一个指向 char 数组的指针

char *aname_seen = malloc(count * (sizeof(char) * 3));

所以aname_seen[i]char

所以

printf("%d: %s vs %s\n", i, aname, aname_seen[i]);

应该是

printf("%d: %s vs %c\n", i, aname, aname_seen[i]);

【讨论】:

    猜你喜欢
    • 2014-12-11
    • 2016-03-17
    • 2021-03-18
    • 1970-01-01
    • 2013-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多