使用sprintf_s拼接字符串时出现栈损坏运行时检查失败求助
解决sprintf_s导致的栈损坏问题
你遇到的运行时检查失败(变量szBuffer1周围栈损坏),核心原因是sprintf_s的缓冲区大小参数传入错误,和szBuffer1的总内存大小无关。
问题代码
void main() { char szBuffer1[128] = { 0 }; char szBuffer2[16] = { 0 }; gets_s(szBuffer1, sizeof(szBuffer1)); gets_s(szBuffer2, sizeof(szBuffer2)); sprintf_s(szBuffer1 + strlen(szBuffer1), sizeof(szBuffer1), "%s", szBuffer2); puts(szBuffer1); printf("%d", strlen(szBuffer1)); }
错误分析
sprintf_s的第二个参数要求传入当前可用的缓冲区剩余大小,而非整个缓冲区的总大小。你现在传入sizeof(szBuffer1),但写入起点是szBuffer1 + strlen(szBuffer1),此时剩余可用空间应为sizeof(szBuffer1) - strlen(szBuffer1)(还要预留1字节给字符串终止符\0)。如果szBuffer1已输入内容的长度加上szBuffer2的长度超过这个剩余值,就会触发越界写入,直接破坏栈结构。
举个例子:若szBuffer1输入了120个字符,剩余空间仅8字节,但szBuffer2输入了10个字符,sprintf_s会尝试写入10字节,超出剩余空间范围,立刻触发栈损坏错误。
修正方案
手动计算剩余可用空间,作为sprintf_s的第二个参数传入:
void main() { char szBuffer1[128] = { 0 }; char szBuffer2[16] = { 0 }; gets_s(szBuffer1, sizeof(szBuffer1)); gets_s(szBuffer2, sizeof(szBuffer2)); size_t used_len = strlen(szBuffer1); // 计算剩余可用空间:总大小 - 已用长度 - 1(预留终止符空间) size_t remaining_size = sizeof(szBuffer1) - used_len - 1; // 提前检查空间是否足够,避免越界 if (remaining_size >= strlen(szBuffer2)) { // 这里传入remaining_size + 1,包含终止符的空间 sprintf_s(szBuffer1 + used_len, remaining_size + 1, "%s", szBuffer2); } else { printf("缓冲区剩余空间不足,无法拼接\n"); } puts(szBuffer1); printf("%d", strlen(szBuffer1)); }
额外优化建议
- 替换
gets_s为fgets,可以避免换行符残留问题,用法示例:fgets(szBuffer1, sizeof(szBuffer1), stdin); - 字符串拼接优先使用
strcat_s,它会自动检查剩余空间,无需手动计算:strcat_s(szBuffer1, sizeof(szBuffer1), szBuffer2);
内容的提问来源于stack exchange,提问作者rocket
相关产品推荐
相关产品推荐

