【问题标题】:I'm getting a segfault and can't seem to find it我遇到了段错误,但似乎找不到
【发布时间】:2011-07-11 01:07:26
【问题描述】:

下面的代码是随机的段错误,我似乎看不出它有什么问题。任何帮助,将不胜感激。我使用 gdb 和核心文件将它隔离到这个函数中。

char* chomp(char *str)
{
   unsigned int scan_ind, curr_ind;

   scan_ind = curr_ind = 0;

   while(str[scan_ind])
   {
      if(str[scan_ind] != 0x0A &&
         str[scan_ind] != 0x0D)
      {
         if(curr_ind != scan_ind)
            str[curr_ind] = str[scan_ind];

         curr_ind++;
      }

      scan_ind++;
   }

   str[curr_ind] = 0;

   return str;
}

【问题讨论】:

  • 是否给它一个以零结尾的字符串?
  • 在 valgrind 出现段错误时,您是否尝试过运行它?

标签: c linux segmentation-fault


【解决方案1】:

该代码看起来不错,至少乍一看是这样。一种可能性是,如果您传入的字符串要么不是以 null 结尾,要么是不可修改的(例如字符串文字)。

对于它的价值,您的功能可以简化很多,类似于:

char *chomp (char *str) {
    char *from = str;                         // This is the pointer for reading.
    char *to = str;                           // This is the pointer for writing.

    while (*from != '\0') {                   // Until end of string.
      if((*from != '\n') && (*from != '\r'))  // Transfer desired characters only.
          *to++ = *from;                      // Only increase write pointer if transferred.
      from++;                                 // Increase read pointer no matter what.
   *to = '\0';                                // Truncate string if necessary.
   return str;                                // And return the in-situ modified string.
}

这对非空终止字符串或字符串文字没有帮助,但它更短一些,更像 C。

【讨论】:

  • 在while(str[scan_ind])中隐式检查空终止符
  • while(str[scan_ind]) 隐式检查空终止符,一直持续到找到字符串的结尾。
  • 最好只测试条件句中的布尔值。尽管*from != '\0' 很可能会产生与*from 相同的机器代码,但前者清楚地表明正在测试指向字符的指针以查找字符串结尾。始终选择可读性而不是简洁性,尤其是在没有运行时成本的情况下。
  • 这个实现不会泄漏内存吗,每个字符串最多只有 2 个字节? (被删除的\r\n 将无法访问,因为免费将免费char* 直到\0)?
  • @Beaks:不,它不会泄漏内存。如果您分配了 100 个字节,那么您对这 100 个字节做了什么 并不重要,这就是您在释放它之前所拥有的。当您将其视为字符串时,将空字符放入其中可能会影响其行为,但这是与内存领域管理完全不同的抽象级别。
【解决方案2】:

您的输入可能是字符串文字(如 chomp("carrot"))还是指向字符串文字的指针?在这种情况下,该函数将失败,因为字符串文字是只读的,并且您写入它。

如果您使用字符串文字作为此函数的输入,请尝试将其复制到缓冲区中,然后调用该函数。更好的是,如果可能的话,重新构造函数,以便立即将 str 复制到动态分配的缓冲区中,然后在函数的其余部分使用该缓冲区,然后返回它。

【讨论】:

  • 这很可能是问题所在。他可能正在尝试写入只读存储器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-16
  • 1970-01-01
  • 1970-01-01
  • 2022-01-25
相关资源
最近更新 更多