C语言中将字符串分割为等长字符串数组的异常问题排查
问题根源:C字符串缺少终止符
\0 你遇到的核心问题是没有给分割后的字符数组添加C字符串必需的空终止符\0。
C语言中,strlen()、printf("%s")这类处理字符串的函数,都是通过寻找\0(ASCII值为0的字符)来判断字符串结束位置的。你的代码里:
- 定义了
char array_chunks[9][3],每个元素仅能存3个字符,没有多余空间放\0 - 用
memcpy复制了3个字符后,没有手动添加\0
这导致每个array_chunks[i]都不是合法的C字符串——函数会从数组起始位置一直向后读取内存,直到碰到某个随机的\0,这就是为什么第二次打印时长度异常,甚至出现段错误(越界访问了不属于程序的内存区域)。
第一次打印看似正常只是巧合:当时内存中array_chunks后面刚好有换行符或其他字符,被printf误判为结束标记,但这是不可靠的非法行为。
修复方案
1. 调整数组大小,预留终止符空间
把每个chunk的数组长度从3改成4,用来容纳3个有效字符+1个\0:
char array_chunks[9][4]; // 3个数据字符 + 1个'\0'
2. 复制后手动添加终止符
每次memcpy完成后,给当前chunk的末尾加上\0:
int n = 9; int chunk = strlen(buffer)/n; // 结果为3 char array_chunks[9][4]; for (int i = 0; i < n; i++){ int starting_point = i*chunk; memcpy(array_chunks[i], buffer + starting_point, chunk); array_chunks[i][chunk] = '\0'; // 关键:添加字符串终止符 printf(":%s\n", array_chunks[i]); }
3. 边界情况处理(可选)
如果原buffer的总长度不是n*chunk的整数倍,最后一块需要单独处理,避免越界复制:
// 假设总长度为total_len int total_len = strlen(buffer); for (int i = 0; i < n; i++){ int starting_point = i*chunk; // 最后一块取剩余的所有字符,最多chunk个 int copy_len = (i == n-1) ? (total_len - starting_point) : chunk; memcpy(array_chunks[i], buffer + starting_point, copy_len); array_chunks[i][copy_len] = '\0'; }
验证修复效果
修改后再执行打印代码:
for (int i =0 ; i<n; i++){ int a = strlen(array_chunks[i]); printf("Len: %d\n", a); printf("Chunk:%s\n", array_chunks[i]); }
会得到符合预期的结果:每个chunk的长度都是3,打印内容也正确,不会出现越界的超长字符串,段错误也会消失。
内容的提问来源于stack exchange,提问作者irti_420
相关产品推荐
相关产品推荐

