使用 memset() 获取“中止陷阱 6”

Posted

技术标签:

【中文标题】使用 memset() 获取“中止陷阱 6”【英文标题】:Getting "Abort trap 6" using memset() 【发布时间】:2021-06-06 17:49:05 【问题描述】:

我对 C 语言比较陌生,所以如果这是一个明显的问题,请多多包涵。我已经到处寻找答案,但无法弄清楚。

我正在编写一个简单的计算器——它将从用户那里进行计算(例如,“1 + 3”,然后返回结果。为了简单起见,我设置了输入缓冲区的长度并强制用户保持在这些范围内。如果他们输入的字符过多,我想提醒他们已经超出限制,并重置缓冲区以便他们可以重新输入。

当它们低于限制时,此功能可以正常工作。当他们超过限制时,它也会正确地给他们一个消息。但是,当他们在输入无效计算后尝试输入 有效 计算时,我得到abort trap: 6。我知道这与我如何重置数组和管理该缓冲区的内存有关,但我的 C 技能还不够敏锐,无法自行诊断问题。

如果有人可以看一下,我真的很感激!我在下面粘贴了我的代码。

#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>

#define BUFFER_SIZE 50

static void ready_for_input()

  printf(">  ");


static char *as_string(char buffer[], int size)

  char *result = (char *)malloc((size + 1) * sizeof(char));
  if (!result)
  
    fprintf(stderr, "calculator: allocation error");
    exit(EXIT_FAILURE);
  

  for (int i = 0; i < size; i++)
  
    result[i] = buffer[i];
  

  // to make it a valid string 
  result[size] = '\0';
  return result;


static char *read_line()

  // put the input into a buffer
  char buffer[BUFFER_SIZE], c;
  int len = 0;

  while (true)
  
    c = getchar();
    if (c == EOF || c == '\n')
    
      // reset if input has exceeded buffer length
      if (len > BUFFER_SIZE)
      
        printf("Calculations must be under 100 characters long.\n");
        memset(buffer, 0, sizeof(buffer));
        len = 0;
        ready_for_input();
      
      else
      
        return as_string(buffer, len);
      
    
    else
    
      buffer[len++] = c;
    
  


static void start_calculator()

  ready_for_input();
  char *line = read_line();
  printf("input received : %s", line);


int main(int argc, char *argv[])

  start_calculator();

【问题讨论】:

if (len &gt; BUFFER_SIZE) -> if (len &gt;= BUFFER_SIZE)。而且您应该将检查 above if (c == EOF || c == '\n') 移动 - 您只是在写入 buffer[len++] 而不检查 len 是否小于它的大小。 纸笔练习:浏览代码,将缓冲区大小设置为 1,看看如何处理溢出。 哦,对了,现在看来很明显——很好的学习机会,谢谢! 需要将c声明为int类型,即EOF的类型,getchar返回的类型。 【参考方案1】:

您无法防止缓冲区溢出,因为您检查它为时已晚。在用户点击回车之前,您应该检查用户是否即将超出缓冲区的大小。

下面的代码稍微改进了检查缓冲区溢出的方式:

static char *read_line()

  // put the input into a buffer
  char buffer[BUFFER_SIZE];
  int c; // getchar should be assigned to an int
  int len = 0;

  while (true)
  
    c = getchar();

    if (len >= BUFFER_SIZE)
    
      // drop everything until EOF or newline
      while (c != EOF && c != '\n')
        c = getchar();
      printf("Calculations must be under 100 characters long.\n");
      memset(buffer, 0, sizeof(buffer));
      len = 0;
      ready_for_input();
    
    else if (c == EOF || c == '\n')
    
      return as_string(buffer, len);
    
    else
    
      buffer[len++] = c;
    
  

另外需要注意的是,gethchar() 应该分配给 int 变量而不是 char,因为您正在检查 EOF (more info about this)

最后,您可能想要检查在 c 中读取一行的更好方法,例如fgets,为缓冲区动态分配内存并使用realloc(或mallocmemmove 的组合)达到限制时将大小加倍,或使用getline

【讨论】:

很好的答案,谢谢。我听说过更好的阅读方式——为了学习,我想从头开始实现一些东西,但如果我要制作一些不是为了学习的东西,我绝对会使用你提到的其他方法之一。再次感谢!

以上是关于使用 memset() 获取“中止陷阱 6”的主要内容,如果未能解决你的问题,请参考以下文章

中止陷阱错误:6 - 它来自哪里? - 数独求解器

中止陷阱:strncat() 出现 6 个错误

C中的“中止陷阱:6”错误?

由于信号,命令失败:中止陷阱:6

C中的中止陷阱6错误

使用 py2app 捆绑 PyQt5 应用程序:不断收到“中止陷阱:6”错误