为何ret已获取内存地址,执行strcpy仍触发Segmentation fault?
段错误原因分析及修复
为啥会触发段错误?
- 你代码里的
"This string literal is arbitrary"是字符串字面量,程序运行时会把它放到只读内存区域(比如rodata段),这块内存只能读,绝对不能写。 strstr(tmp, "literal")返回的ret指针,指向的就是这个只读区域里"literal"的起始位置。你调用strcpy(ret, "")想往这块只读内存里写东西,直接违反了内存访问规则,系统就抛出段错误了。- 还有个逻辑顺序问题:你先执行
strcpy再判断ret是否为空,如果strstr没找到子串,ret是NULL,这时候strcpy直接就崩了。
怎么改?
要修改字符串内容,得先把字符串放到可写的内存里,比如栈上的数组或者堆内存:
方法1:用栈上的数组(简单直接)
#include <stdio.h> #include <string.h> int main() { // 把字符串字面量复制到栈上的数组,数组是可写的 char tmp[] = "This string literal is arbitrary"; char *ret = strstr(tmp, "literal"); if (ret) { // 直接把第一个字符改成'\0'就清空后面内容了,比strcpy高效 *ret = '\0'; printf("找到子串,地址:%p\n", ret); printf("修改后的字符串:%s\n", tmp); } else { printf("没找到子串\n"); } return 0; }
方法2:用堆内存(适合字符串长度不确定的情况)
#include <stdio.h> #include <string.h> #include <stdlib.h> int main() { const char *src = "This string literal is arbitrary"; // 分配足够内存,复制原字符串到堆上 char *tmp = malloc(strlen(src) + 1); if (!tmp) { perror("内存分配失败"); return 1; } strcpy(tmp, src); char *ret = strstr(tmp, "literal"); if (ret) { strcpy(ret, ""); printf("找到子串,地址:%p\n", ret); printf("修改后的字符串:%s\n", tmp); } else { printf("没找到子串\n"); } free(tmp); // 用完堆内存记得释放 return 0; }
额外提醒
- 字符串字面量就算用
char*指向它,也不能修改内容,这是C语言里的未定义行为,大部分系统都会直接崩溃。 - 调用
strstr这类可能返回NULL的函数,一定要先判断返回值不为空,再做后续操作,避免空指针访问崩溃。
内容的提问来源于stack exchange,提问作者utkarh_gupta
相关产品推荐
相关产品推荐

