C++实现pad_left左补下划线功能出现死循环、段错误问题求助
问题排查
核心问题原因
- 无符号整数下溢导致异常循环:
strlen返回值为无符号类型size_t,当原字符串长度大于参数n时,n - strlen(a)会发生无符号下溢,得到一个极大的正整数,导致for循环执行次数远超预期,触发内存越界、段错误或无限循环。 - 插入逻辑不完整:
insert_begin仅实现了原字符串右移,没有给首位置赋值为'_',导致填充位置是内存垃圾值。 - 内存空间不足:你的测试用例中定义的
char a[5]仅能容纳长度为4的字符串(含末尾\0),要填充到长度10需要至少11字节空间,内存不足引发栈溢出,破坏栈上的循环变量、返回地址等数据,进一步触发异常。 - 缺少边界判断:没有先判断原字符串长度是否已经大于等于
n,这种场景按要求应该直接返回不做处理。 - 效率低下:每次插入单字符就遍历全串右移,时间复杂度为O(n²),存在优化空间。
解决方案
实现思路
遵循C风格字符串操作约定(调用方保证传入的内存空间足够容纳长度为n的字符串,即至少有n+1字节),一次性完成移位和填充,避免多次遍历:
- 先计算原字符串长度,若长度 >=n 直接返回
- 计算需要填充的下划线个数
pad_cnt = n - 原长度 - 从原字符串末尾(包括
\0)开始,将所有字符向右移动pad_cnt位 - 将前
pad_cnt个位置统一填充为'_'
完整修正代码
#include <iostream> #include <cstring> using namespace std; void printChar(char *a) { int i = 0; while(a[i] != '\0') cout << a[i]; cout << endl; } void pad_left(char *a, int n) { int old_len = strlen(a); // 边界判断:原长度已经满足要求直接返回 if (old_len >= n) { return; } int pad_cnt = n - old_len; // 从后往前移位,包括末尾的\0 for (int i = old_len; i >= 0; i--) { a[i + pad_cnt] = a[i]; } // 填充前pad_cnt个位置为下划线 for (int i = 0; i < pad_cnt; i++) { a[i] = '_'; } } int main() { ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0); // 开足够的空间:要容纳长度10的字符串需要11字节(含\0) char a[11] = "test"; pad_left(a, 10); printChar(a); return 0; }
注意事项
调用pad_left函数前必须保证a指向的内存空间至少有n+1字节,否则会出现内存越界问题,这是C风格字符串操作的标准约定,符合题目不返回新指针的要求。
内容的提问来源于stack exchange,提问作者phuc_otaku
相关产品推荐
相关产品推荐

