C语言自定义实现strcat过程中realloc报无效指针错误的排查
代码报错
realloc(): invalid pointer的根因定位与认知偏差梳理 直接触发报错的原因
realloc的入参有强制校验规则:它接收的第一个指针,必须是此前通过malloc/calloc/realloc申请的堆内存地址,不支持传入栈内存、全局静态内存的指针。
你的测试代码里传给StrCat的目标参数dest4,是栈帧上定义的固定长度字符数组:
char dest4[100] = "this is dest of cat";
这块内存是编译期就分配的栈空间,完全不属于堆内存的管理范围,realloc对这类非堆地址做内存调整时,会直接触发内部的内存元数据校验失败,抛出invalid pointer的运行时错误。
设计逻辑与代码实现的错位问题
哪怕把栈内存传参的问题修正为合法的堆内存,当前代码的执行流也和你原本设计的逻辑存在多处完全颠倒的偏差:
- 指针保存时机错误
你计划保存dest的首地址作为函数返回值,但代码里的char *start = dest;是在调用realloc之前执行的。只要realloc执行成功,它会直接释放原dest指向的内存块,返回新的堆内存地址,此时你保存的start指向的是已经被释放的旧地址,哪怕运行不报错,返回给调用方的也是无效野指针。 - 拼接顺序完全倒置
两个while循环的写入位置是realloc之后的dest指针位置,也就是新分配内存块的首地址。实际执行时的流程是:先把src的全部内容从新内存的开头开始写入,写完src后,再接着把temp里存的原dest内容往后追加,最终拼出来的字符串是「src内容在前、原dest内容在后」的顺序,和strcat要求的「原dest在前、src在后」的拼接目标完全相反。 - 副本创建时机错误
你原本计划先备份dest的内容,再调整dest的内存大小,但代码是先调用realloc,才执行strcpy(temp, dest)把内容拷贝到临时副本,此时拷贝的已经不是你要备份的原始dest字符串内容了。
对strcat原生功能的认知偏差
标准库strcat本身没有任何内置的内存扩容逻辑,它的设计前提非常明确:调用者必须提前保证目标内存块有足够的剩余空间,能完整容纳原dest字符串、src字符串和末尾的字符串终止符\0。
你在实现里加入realloc的设计,本身就和原函数的行为不兼容:C语言是值传递机制,函数内部对dest指针做realloc调整后得到的新内存地址,根本没法同步回调用方的实参,单靠函数返回值也无法覆盖所有正常的strcat调用场景。
其他潜在运行隐患
- 没有对
realloc的返回值做空校验:如果堆内存不足导致分配失败,realloc会返回NULL,后续直接通过空指针写入内容会直接触发段错误。 - 没有对temp的malloc结果做校验:如果临时副本内存申请失败,后续的字符串拷贝操作同样会触发空指针访问。
内容的提问来源于stack exchange,提问作者NoobCoder
相关产品推荐
相关产品推荐

