如何实现无需中间字符串将字符串插入另一字符串指定位置的C函数?
核心问题说明
你当前代码的问题出在C语言的函数参数值传递规则:函数参数char* M是外部传入指针的拷贝,你在函数内通过M = realloc(...)修改的只是拷贝后的值,外部的原指针并不会同步更新。如果realloc触发了内存块迁移(也就是原地址空间不够,申请了新的地址并释放了旧地址),外部原指针就会变成野指针,自然无法得到正确结果,甚至会触发崩溃。
可行实现方案
有两种常用的实现方式,均不需要中间字符串:
方案1:函数返回新的字符串指针
这是最简洁、兼容性最好的实现方式:
#include <stdlib.h> #include <string.h> // 函数返回扩容后的新指针,调用方需要接收返回值替换原指针 char* insert(char* M, const char* T, int i) { // 提前计算长度,避免重复调用strlen int len_M = strlen(M); int len_T = strlen(T); // 边界校验:插入位置不能超过原字符串长度 if (i < 0 || i > len_M) { return M; } // 扩容,保留realloc返回值到临时变量,避免扩容失败丢失原指针 char* new_ptr = realloc(M, len_M + len_T + 1); if (new_ptr == NULL) { // 扩容失败返回原指针,也可根据需求做错误处理 return M; } M = new_ptr; // 从后往前移动原字符串后半段(包含结束符\0) for (int j = len_M; j >= i; j--) { M[j + len_T] = M[j]; } // 复制插入字符串到目标位置 for (int j = 0; j < len_T; j++) { M[i + j] = T[j]; } return M; }
调用方式调整为:
char *s = malloc(3); char *c = malloc(18); strcpy(s, "as"); strcpy(c, "bcdefghijklmnopqr"); // 接收返回值更新原指针 s = insert(s, c, 1); // 使用完记得free(s)和free(c)避免内存泄漏
方案2:传入二级指针修改原指针
如果要求函数返回值为void,可以通过传入二级指针实现对外部原指针的修改:
#include <stdlib.h> #include <string.h> void insert(char** M, const char* T, int i) { if (M == NULL || *M == NULL || T == NULL) { return; } int len_M = strlen(*M); int len_T = strlen(T); if (i < 0 || i > len_M) { return; } char* new_ptr = realloc(*M, len_M + len_T + 1); if (new_ptr == NULL) { return; } *M = new_ptr; for (int j = len_M; j >= i; j--) { (*M)[j + len_T] = (*M)[j]; } for (int j = 0; j < len_T; j++) { (*M)[i + j] = T[j]; } }
调用方式调整为:
char *s = malloc(3); char *c = malloc(18); strcpy(s, "as"); strcpy(c, "bcdefghijklmnopqr"); // 传入指针的地址 insert(&s, c, 1);
注意事项
- 只有堆上分配的字符串(通过
malloc/calloc/realloc申请的)才能传入该函数,栈上的字符串数组、字符串常量都不能作为参数M传入,否则realloc会触发未定义行为。 - 记得在使用完字符串后调用
free释放内存,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Rafik Bouloudene
相关产品推荐
相关产品推荐

