查看: 189|回复: 3

[C/C++] 【求助】代码SegFault

[复制链接]

0

技术

9

魅力

1

原创

版主

禁止访问

Rank: 7Rank: 7Rank: 7

积分
7674
人气
176
分享
52

最佳新人活跃会员

发表于 2024-7-27 14:34:31 | 显示全部楼层 |阅读模式
SegFault函数:

[C++] 纯文本查看 复制代码
void Lexer::FormatInput()
{
    // 去除所有空格
    // erase_if()函数会找到所有空格,并把他们移动到字符串末尾
    // 并返回一个指向最后一个非空格字符的迭代器,我们可以使用
    // erase()删除这些空格字符(此代码正常)
    input_.erase(std::remove_if(input_.begin(), input_.end(), isspace), input_.end());

    // 去除字符串末尾的特殊符号和等号(SegFault)
    // while (!std::isalnum(input_.back()) || !isOperator(input_.back())// 代码在此处segfault || input_.back() == '=') {
    //     input_.pop_back();
    // }
}

已知是isOperator的问题,但是isOperator函数本身应该是没有问题的(在另一处能正确调用),传入的参数也是和isalmun相同的input_.back()
[C++] 纯文本查看 复制代码
bool Lexer::isOperator(char ch)
{
    return ch == '+' || ch == '-' || ch == '*' || ch == '/' ||
        ch == '^' || ch == '|' || ch == '(' || ch == ')';
}

小菜鸡一枚~
Gitee主页:https://gitee.com/juruoqwq

4

技术

17

魅力

6

原创

版主

禁止发言

Rank: 7Rank: 7Rank: 7

积分
5367
人气
208
分享
36

最佳新人活跃会员

发表于 2024-7-27 20:58:20 | 显示全部楼层
chatgpt:
Segmentation fault(SegFault)通常表示你的程序试图访问未分配的内存区域。在你的代码中,可能的原因是尝试对空的字符串调用 input_.back(),这会导致程序崩溃。具体到你的 FormatInput 函数,以下几点需要检查:

检查字符串是否为空:在调用 input_.back() 之前,确保字符串不为空,否则访问 input_.back() 会导致未定义行为。

确认 isOperator 函数的行为:虽然你说 isOperator 函数在其他地方调用时工作正常,但还是要确保它在所有情况下都能正常处理。

下面是修改后的代码,其中加入了空字符串的检查:

cpp
复制代码
void Lexer::FormatInput()
{
    // 去除所有空格
    input_.erase(std::remove_if(input_.begin(), input_.end(), isspace), input_.end());

    // 去除字符串末尾的特殊符号和等号
    while (!input_.empty() && (!std::isalnum(input_.back()) && !isOperator(input_.back()) && input_.back() != '=')) {
        input_.pop_back();
    }
}
解释:
检查是否为空:

cpp
复制代码
while (!input_.empty() && (!std::isalnum(input_.back()) && !isOperator(input_.back()) && input_.back() != '=')) {
这行代码确保在调用 input_.back() 之前,字符串 input_ 不为空。如果字符串为空,条件 !input_.empty() 会为 false,从而跳出循环,避免访问无效内存。

修正条件判断:
你的原始条件检查 input_.back() == '=' 的逻辑可能有些问题。用 && 连接三个条件是为了确保字符既不是字母数字、也不是运算符,并且也不是等号。如果是这样,它才会被 pop_back() 移除。

这个修改后的代码能有效防止空字符串导致的 SegFault 错误。如果仍然遇到问题,可以检查其他部分的代码,确保在调用 FormatInput() 之前 input_ 被正确初始化和赋值。
YF工作室驻x64论坛分部
工作室曾开发的软件:YFSafe安全软件,YFChat在线聊天软件,MBRTools等。
欢迎有能力的你加入我们一起共同进步。请发邮件至yfstudio2021@outlook.com

0

技术

8

魅力

0

原创

共绘星辰

Rank: 6Rank: 6

积分
8003
人气
103
分享
296

灌水之王最佳新人活跃会员

发表于 2024-7-28 08:55:01 | 显示全部楼层
看起来,`FormatInput()`函数中的代码段被注释掉了,导致无法正确去除字符串末尾的特殊符号和等号。但是,即使这部分代码被取消注释,它仍然可能引发段错误(Segmentation Fault)。

问题可能出在`isOperator()`函数的调用上。如果`input_.back()`是一个非法字符(例如,一个空字符串),那么调用`isOperator(input_.back())`可能会导致未定义的行为,从而引发段错误。

为了解决这个问题,你可以在调用`isOperator()`之前检查`input_`是否为空。如果为空,则不执行任何操作。以下是修改后的代码:

```cpp
void Lexer::FormatInput()
{
    // 去除所有空格
    input_.erase(std::remove_if(input_.begin(), input_.end(), isspace), input_.end());

    // 去除字符串末尾的特殊符号和等号
    while (!input_.empty() && (!std::isalnum(input_.back()) || !isOperator(input_.back()) || input_.back() == '=')) {
        input_.pop_back();
    }
}
```

这样,只有当`input_`不为空时,才会尝试访问其最后一个字符并进行相应的操作。这应该可以防止段错误的发生。
由讯飞星火生成

0

技术

9

魅力

1

原创

版主

禁止访问

Rank: 7Rank: 7Rank: 7

积分
7674
人气
176
分享
52

最佳新人活跃会员

 楼主| 发表于 2024-7-28 14:06:15 | 显示全部楼层
YFSafe 发表于 2024-7-27 20:58
chatgpt:
Segmentation fault(SegFault)通常表示你的程序试图访问未分配的内存区域。在你的代码中,可能 ...

hhh怎么各大AI都提到空字符串,校验的代码在构造函数里,不会是空串
小菜鸡一枚~
Gitee主页:https://gitee.com/juruoqwq
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表