使用memcpy拼接C字符串出现段错误,求问题排查与解决
你的字符串拼接函数段错误的原因及修复方案
咱们直接拆解问题,你的代码有几个致命问题,直接导致了段错误:
1. 试图修改只读的字符串字面量
你提到str1是字符串字面量(比如"hello_world"这种写法),这类字符串会被存储在程序的只读内存区域(比如TI-84 CE的.rodata段),硬件/系统会禁止对这块区域的写入操作。你的memcpy直接往str1里写数据,这必然触发段错误——这是最核心的原因。
2. 拼接起始位置计算错误
strlen(str1)返回的是字符串的有效长度(不包含末尾的'\0'),所以str1的终止符位置是str1 + strlen(str1)。而你写的strlen(str1)-1,会让你从原字符串的最后一个有效字符位置开始写入,直接覆盖掉原字符串的最后一个字符,还会导致拼接后的字符串结构混乱(比如没有正确的终止符,或者原字符串内容被破坏)。
3. 未检查目标内存空间是否足够
就算str1不是字面量,如果你没有提前确保str1的内存空间能装下原字符串+str2+终止符,memcpy会越界写入,这属于未定义行为,大概率会触发段错误或者破坏其他内存数据。
针对TI-84 CE环境的修复方案
考虑到TI-84 CE内存有限,这里提供两种实用的修复方式:
方案一:动态分配内存(灵活但需手动释放)
适合不确定拼接后字符串长度的场景,我们重新分配一块足够的内存来存储拼接结果:
#include <stdlib.h> #include <string.h> char *concat(const char *str1, const char *str2) { size_t len1 = strlen(str1); size_t len2 = strlen(str2); // 分配足够内存:原长度+新长度+1(终止符) char *result = malloc(len1 + len2 + 1); if (result == NULL) { return NULL; // 内存分配失败,返回空指针 } // 复制原字符串 memcpy(result, str1, len1); // 复制第二个字符串(包括它的终止符) memcpy(result + len1, str2, len2 + 1); return result; }
⚠️ 注意:调用这个函数后,一定要记得用free(result)释放内存,避免TI-84上出现内存泄漏。
方案二:预先分配固定大小的缓冲区(更适合嵌入式环境)
如果能提前预估拼接后的最大长度,用预先定义的数组作为缓冲区更高效,不需要动态分配:
#include <string.h> // 根据你的需求定义最大长度,比如256字节 #define MAX_CONCAT_SIZE 256 char *concat_to_buffer(char *dest, const char *str1, const char *str2) { size_t len1 = strlen(str1); size_t len2 = strlen(str2); // 检查缓冲区是否足够装下拼接后的内容 if (len1 + len2 + 1 > MAX_CONCAT_SIZE) { return NULL; // 空间不足,返回错误 } // 复制第一个字符串 memcpy(dest, str1, len1); // 从第一个字符串的终止符位置开始复制第二个字符串 memcpy(dest + len1, str2, len2 + 1); return dest; } // 使用示例: char concat_buffer[MAX_CONCAT_SIZE]; // 把"Hello "和str2拼接到buffer里 concat_to_buffer(concat_buffer, "Hello ", str2);
这个方案不需要动态内存操作,更适合TI-84这类资源有限的嵌入式设备,只要确保缓冲区大小足够就行。
内容的提问来源于stack exchange,提问作者Hello Goodbye
相关产品推荐
相关产品推荐

