You need to enable JavaScript to run this app. C++拆分动态char为20字符块时遇到存储覆盖、乱码、memcpy输出失效问题
优惠活动
大模型
产品
解决方案
定价
更多

C++拆分动态char为20字符块时遇到存储覆盖、乱码、memcpy输出失效问题

两类实现的问题根因分析

初版实现的两处核心错误

  • 栈变量生命周期误用:循环内部定义的char buff[blockSize]是栈上的临时局部变量,每次循环执行结束,这块栈内存就会被系统回收复用,不再保存之前拷贝的字符串内容。循环计算阶段打印时,这块栈空间还没被后续操作覆盖,所以能读到临时的正确拆分内容;进入校验阶段遍历指针数组时,所有存进chunks的栈地址都指向被反复覆写的同一块栈内存,最后就会全变成最后一次循环写入的全0xff残留内容。
  • 字符串未补结束符:每次拷贝固定20字节到buff后,没有在内容末尾添加字符串结束符\0。串口打印字符串的逻辑是从起始地址逐字节读取,直到碰到\0才停止,所以打印完20个拷贝的字符后,会继续读取buff内存后方的随机栈数据,就出现了⸮!这类乱码。

修改后实现的核心错误

  • 把存储结构改成char chunks[6][20]二维数组的方向是正确的,但依然没有给每个块补字符串结束符。每个块20字节的空间全用来存了拷贝的字符,没有预留位置放\0;校验时串口打印的char*指针会持续向后读取内存,直到碰到原长字符串末尾自带的\0才停止,表现出来的效果就是从当前块起始位置一直打印到长串末尾,容易让人误以为memcpy的长度限制没生效。
合规拆分实现方案
  • 修正存储逻辑:杜绝把循环内栈临时数组的地址存入长生命周期的指针数组,使用连续的固定存储区(比如全局/静态的二维字符数组)保存拆分后的块内容。
  • 适配字符串打印规则:在每个块的存储空间里预留1字节放结束符,拷贝完成后手动在内容末尾补\0。
  • 增加边界判断:拷贝时不能硬凑固定20字节长度,要根据源串剩余的实际长度取较小值,避免读源串越界内存。

参考正确实现片段:

#define BLOCK_SIZE 20
#define MAX_BLOCKS 6
// 每个块多留1字节存结束符
char chunks[MAX_BLOCKS][BLOCK_SIZE + 1];
char* largeWord = "待拆分的长字符串";
size_t srcTotalLen = strlen(largeWord);
size_t totalBlocks = (srcTotalLen + BLOCK_SIZE - 1) / BLOCK_SIZE;

for (size_t blockIdx = 0; blockIdx < totalBlocks; blockIdx++) {
    size_t offset = blockIdx * BLOCK_SIZE;
    // 计算当前块实际需要拷贝的长度
    size_t realCopyLen = (srcTotalLen - offset) >= BLOCK_SIZE 
                        ? BLOCK_SIZE 
                        : (srcTotalLen - offset);
    memcpy(chunks[blockIdx], largeWord + offset, realCopyLen);
    // 关键操作:补字符串结束符
    chunks[blockIdx][realCopyLen] = '\0';
}

关键注意事项

  • 二维字符数组的每一行长度要设置为块大小 + 1,预留专门的结束符位置,否则20字节全存字符依然会出现打印越界问题。
  • 源串长度不足20的最后一块,要按实际剩余长度拷贝,不能硬读20字节的越界内存。
  • 如果要保留char* chunks[]的指针数组结构,必须把每个块的存储空间定义为静态/全局的连续内存,不能使用循环内的栈临时变量。

内容的提问来源于stack exchange,提问作者jLynx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.28 09:54:01