使用strcat_s()遇运行时错误:动态char*触发缓冲区过小断言
strcat_s()动态字符串拼接触发「Buffer is too small」断言的解决办法
问题核心原因
你代码里的关键错误是对动态分配的char*指针使用sizeof获取缓冲区大小:
- 对于栈上的数组(比如
str3[100]),sizeof(str3)会返回整个数组的总字节数(100),这完全符合strcat_s对第二个参数的要求(目标缓冲区的总容量)。 - 但对于
char* str1 = new char[100]这种动态分配的指针,sizeof(str1)返回的是指针本身的字节数(64位系统是8,32位系统是4),远小于实际分配的100字节空间。当strcat_s检查拼接后的字符串长度时,发现远超传入的8字节限制,直接触发缓冲区过小的调试断言。
修正后的代码
#include "Mystring.h" #include <iostream> #include <cstring> #include <cctype> int main() { const size_t str1_size = 100; const size_t str2_size = 10; char* str1 = new char[str1_size]; char* str2 = new char[str2_size]; strcpy_s(str1, strlen("Hello") + 1, "Hello"); std::cout << str1; strcpy_s(str2, strlen(" World") + 1, " World"); std::cout << str2; // 传入实际分配的缓冲区总大小,而非sizeof(str1) strcat_s(str1, str1_size, str2); std::cout << str1; char str3[100] = "Hello"; char str4[10] = " World"; strcat_s(str3, sizeof(str3), str4); // 记得释放动态分配的内存 delete[] str1; delete[] str2; }
底层原理说明
- 栈数组的大小是编译期确定的,编译器可以直接通过数组名获取其总字节数,因此
sizeof对栈数组能正确返回缓冲区容量。 - 动态分配的内存是运行期向堆申请的,编译器无法通过指针得知其指向的内存块实际大小,
sizeof只能识别指针类型本身的长度。 - strcat_s作为安全字符串函数,必须明确知道目标缓冲区的总容量,才能计算拼接后的字符串长度是否超出限制,从根源避免传统strcat函数的缓冲区溢出风险。
内容的提问来源于stack exchange,提问作者Harry Vu
相关产品推荐
相关产品推荐

