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

使用strcpy_s()和strcat_s()处理动态分配字符串时程序崩溃问题

解决你的C++字符串拼接崩溃问题

嘿,我一眼就发现问题出在strcpy_s()和strcat_s()的参数使用上——这两个安全字符串函数的第二个参数要求的是目标缓冲区的总大小,而不是你传入的源字符串长度。咱们一步步来修复:

问题根源拆解

1. strcpy_s的参数错误

你写的代码里:

strcpy_s(tempstr, oldSize, *theStr);

这里的oldSize是原字符串的长度(不包含\0终止符),但strcpy_s需要的是目标缓冲区tempstr的总字节数(也就是oldSize + toAdd + 1)。当原字符串长度等于oldSize时,加上终止符需要oldSize+1字节,而你告诉函数缓冲区只有oldSize字节,直接触发了安全检查的崩溃。

2. strcat_s的参数错误

同样的问题出现在拼接时:

strcat_s(tempstr, toAdd, AddStr);

strcat_s的第二个参数需要的是目标缓冲区的总大小(或者剩余可用空间),而不是要拼接的字符串长度。你传入toAdd会让函数误以为缓冲区只有这么大,拼接时必然超出范围导致崩溃。

3. 遗漏的头文件

另外,main里用了numeric_limits<streamsize>::max(),但没包含<limits>头文件,这会导致编译错误,需要补上。

修复后的完整代码

#include<iostream>
#include<cstring>
#include<limits>  // 补充这个头文件
using namespace std;

void addChars(char** theStr);

int main() {  // 标准C++里main应该返回int,不是void
    const int STR_SIZE = 10;
    char* str = new char[STR_SIZE + 1];
    
    cout << "Enter 10 chars:" << endl;
    cin.getline(str, STR_SIZE + 1);
    
    if (cin.fail()) {
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');  // 加上'\n'更精准,只忽略到换行符
    }
    
    addChars(&str);
    cout << str << endl;
    
    delete[] str;  // 别忘了释放内存,避免泄漏
    system("pause");
    return 0;
}

void addChars(char ** theStr) {
    int toAdd;
    int oldSize;
    char* AddStr;
    char* tempstr;
    
    cout << "How many chars to add:" << endl;
    cin >> toAdd;
    
    AddStr = new char[toAdd + 1];
    cout << "Enter the chars: " << endl;
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');  // 替换原来的cin.ignore(),确保清空输入缓存
    cin.getline(AddStr, toAdd + 1);
    
    oldSize = strlen(*theStr);
    const int newSize = oldSize + toAdd + 1;
    tempstr = new char[newSize];
    
    // 修复strcpy_s的参数:传入目标缓冲区总大小
    strcpy_s(tempstr, newSize, *theStr);
    // 修复strcat_s的参数:传入目标缓冲区总大小
    strcat_s(tempstr, newSize, AddStr);
    
    delete[] *theStr;
    delete[] AddStr;  // 别忘了释放AddStr的内存
    *theStr = tempstr;
}

额外的优化点

  • 把void main()改成标准的int main()并返回0,符合C++标准规范。
  • 补充了AddStr和main中str的内存释放,避免内存泄漏。
  • 把cin.ignore()改成cin.ignore(numeric_limits<streamsize>::max(), '\n'),更精准地清空输入缓存,避免残留的换行符影响后续输入。

内容的提问来源于stack exchange,提问作者Avraham Batoniashvili

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:33:42