You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复char数组引发的Run-Time Check Failure #2缓冲区溢出问题?

问题分析与解决方案

核心问题定位

  1. 缓冲区溢出根源

    • 定义char pword[Size]时,Size=10,但C风格字符串需要末尾的'\0'作为结束标记,这个数组最多只能容纳9个有效字符。输入10个字符的密码时会直接溢出栈空间,触发栈损坏错误。
    • 代码中错误地将空字符写成'\\0'(多了一个反斜杠),导致循环无法正确识别字符串结束位置,count持续递增,越界访问数组进一步破坏栈结构。
    • bool state = NULL是错误用法,NULL是指针类型的空值,布尔类型应初始化为false。
  2. 逻辑漏洞

    • 未验证密码总长度是否为10,psize变量完全未使用。
    • 密码规则是恰好4个小写字母+6个数字,原代码判断totall >4 || totaln>6逻辑错误,应该检查totall !=4 || totaln !=6,同时确保总长度是10。
  3. 错误的动态分配尝试

    • 你写的pword[Size]= (char*)malloc(sizeof(char))={};完全不符合C/C++语法。动态分配C风格数组需要先声明指针,再分配足够的内存空间。

修复后的完整代码

// 验证输入密码是否有效:10字符,4个小写字母+6个数字,顺序不限
#include<iostream>
#include<cctype>
#include<cstring>

using namespace std;

int main()
{
    const int PWD_LENGTH = 10;
    // 数组大小设为11,预留'\0'的位置
    char pword[PWD_LENGTH + 1];
    int count = 0;
    int letter_count = 0;
    int digit_count = 0;
    bool is_valid = false;

    while (!is_valid) 
    {
        cout << "请输入10位密码(4个小写字母+6个数字):" << endl;
        // 使用cin.getline避免溢出,限制读取10个字符+1个'\0'
        cin.getline(pword, PWD_LENGTH + 1);

        int pwd_size = strlen(pword);
        letter_count = 0;
        digit_count = 0;
        is_valid = true;

        // 先检查长度是否符合要求
        if (pwd_size != PWD_LENGTH) {
            cout << "错误!密码必须是10个字符。" << endl;
            is_valid = false;
            continue;
        }

        // 遍历每个字符验证类型
        for (count = 0; count < PWD_LENGTH; ++count) {
            if (islower(pword[count])) {
                letter_count++;
            } else if (isdigit(pword[count])) {
                digit_count++;
            } else {
                // 既不是小写字母也不是数字
                cout << "错误!所有字符必须是小写字母或数字。" << endl;
                is_valid = false;
                break;
            }
        }

        // 验证字母和数字的数量是否符合规则
        if (is_valid && (letter_count != 4 || digit_count != 6)) {
            cout << "错误!密码必须包含恰好4个小写字母和6个数字。" << endl;
            is_valid = false;
        }
    }
   
    cout << "你输入的密码是:" << pword << endl;
    cout << "密码中小写字母的数量是:" << letter_count << endl;
    cout << "密码中数字的数量是:" << digit_count << endl;
      
    return 0;
}

正确的动态内存分配方式

1. C风格malloc/free

如果要用C的动态分配,需要给指针分配足够的内存(包含'\0'的空间):

const int PWD_LENGTH = 10;
// 分配11个字符的空间:10个密码字符 + 1个'\0'
char* pword = (char*)malloc((PWD_LENGTH + 1) * sizeof(char));
// 使用前检查是否分配成功
if (pword == nullptr) {
    cerr << "内存分配失败" << endl;
    return 1;
}

// 使用完成后必须释放内存
free(pword);
pword = nullptr; // 避免野指针

2. C++风格new/delete

更符合C++规范的方式:

const int PWD_LENGTH = 10;
char* pword = new char[PWD_LENGTH + 1];
// 可选:用nothrow版本避免抛出异常
char* pword = new(nothrow) char[PWD_LENGTH + 1];
if (pword == nullptr) {
    cerr << "内存分配失败" << endl;
    return 1;
}

// 使用后释放
delete[] pword;
pword = nullptr;

3. 更推荐的C++方式:std::string

在C++中,完全没必要手动管理C风格字符数组,直接用std::string可以自动处理内存,避免缓冲区溢出:

#include<string>
// ...
string pword;
while (!is_valid) {
    cout << "请输入10位密码:" << endl;
    cin >> pword;
    // 直接用pword.size()获取长度,无需处理'\0'
    if (pword.size() != 10) {
        cout << "错误!密码必须是10个字符。" << endl;
        continue;
    }
    // 遍历验证字符更方便
    for (char c : pword) {
        if (islower(c)) {
            letter_count++;
        } else if (isdigit(c)) {
            digit_count++;
        } else {
            cout << "错误!所有字符必须是小写字母或数字。" << endl;
            is_valid = false;
            break;
        }
    }
    // 验证数量规则...
}

内容的提问来源于stack exchange,提问作者Henry Lj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 18:53:20