重写strcat函数遇二级指针打印NULL及段错误,求修复方案
修复自定义my_strcat的段错误与NULL输出问题
核心错误点
- 参数类型与传递完全错误:main函数里的
str是栈上固定大小的数组,你强制将其转为char**传递给my_strcat属于严重类型违规。栈数组的地址不可修改,也不能用realloc扩容,且强制转换后会把字符串第一个字符的ASCII值当作指针地址,直接触发非法内存访问。 - my_strlen调用逻辑错误:
my_strlen((char *)dest)是把char**类型的指针直接转成char*,相当于把指针本身的内存内容当成字符串,完全无法获取目标字符串的真实长度,正确写法应为my_strlen(*dest)(*dest才是指向目标字符串的指针)。 - realloc使用错误:你修改的是函数形参
dest,而非外部传入的指针本身,且realloc的第一个参数应为原堆指针(即*dest)而非dest。修改形参不会影响外部变量,必须将realloc的返回值赋值给*dest,同时要检查分配是否成功。 - 指针优先级与赋值错误:
*dest[count]的优先级逻辑错误,[]比*优先级高,实际会解析为*(dest[count]),正确写法是(*dest)[count];最后添加终止符的*dest[count] += '\0'是错误操作,应直接赋值为'\0'。
修复后的代码(动态扩容版本)
该版本支持自动扩容,要求目标字符串为堆分配内存:
#include <stdlib.h> #include <stdio.h> #include <string.h> // 用于strcpy初始化堆字符串 #ifndef MY_STRING_H #define MY_STRING_H int my_strlen(const char *str) { int count; for (count = 0; str[count] != '\0'; ++count); return count; } // dest必须是指向堆分配char指针的指针,禁止传入栈数组 void my_strcat(char **dest, const char *src) { if (dest == NULL || *dest == NULL || src == NULL) { return; // 空指针边界检查 } size_t srcSize = my_strlen(src); size_t destSize = my_strlen(*dest); // 分配内存时要额外+1存储字符串终止符 char *newDest = realloc(*dest, destSize + srcSize + 1); if (newDest == NULL) { perror("realloc failed"); return; } *dest = newDest; // 更新外部的指针地址 // 定位目标字符串末尾 int count; for (count = 0; (*dest)[count] != '\0'; ++count); // 复制源字符串内容 for (int count2 = 0; src[count2] != '\0'; ++count2) { (*dest)[count] = src[count2]; count++; } (*dest)[count] = '\0'; // 添加字符串终止符 } int main (){ // 使用堆分配字符串,栈数组无法支持realloc扩容 char *str = malloc(80); if (str == NULL) { perror("malloc failed"); return 1; } strcpy(str, "these strings"); // 初始化堆字符串 my_strcat(&str, "are "); my_strcat(&str, "concatenated."); printf("%s\n", str); free(str); // 释放堆内存,避免泄漏 return 0; } #endif // MY_STRING_H
标准库风格实现(固定缓冲区版本)
如果要复刻标准strcat的逻辑(要求目标缓冲区有足够预分配空间),无需二级指针和realloc:
#include <stdio.h> #ifndef MY_STRING_H #define MY_STRING_H int my_strlen(const char *str) { int count; for (count = 0; str[count] != '\0'; ++count); return count; } // 标准strcat实现:要求dest有足够容纳拼接后内容的空间 void my_strcat(char *dest, const char *src) { if (dest == NULL || src == NULL) { return; } // 定位目标字符串末尾 char *d = dest; while (*d != '\0') { d++; } // 复制源字符串 while (*src != '\0') { *d = *src; d++; src++; } *d = '\0'; } int main() { char str[80] = "these strings"; my_strcat(str, "are "); my_strcat(str, "concatenated."); printf("%s\n", str); return 0; } #endif // MY_STRING_H
内容的提问来源于stack exchange,提问作者Bot Ellis
相关产品推荐
相关产品推荐

