使用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
相关产品推荐
相关产品推荐

