C语言中修改字符串字面量引发段错误的原因解析
段错误原因分析与修复方案
核心原因
- 代码里
char *path = "c/c/c/c/c";中的"c/c/c/c/c"是字符串字面量,这类数据会被编译器放到程序的只读内存段(.rodata),操作系统会禁止对该区域执行写入操作。 - 当你执行
*end = '\0';时,试图通过strrchr返回的指针修改只读内存里的内容,直接触发内存保护机制,导致段错误。
修复方案
要解决问题,需要把字符串放到可修改的内存区域,有两种常用方式:
方式1:使用栈上的字符数组
把字符串字面量复制到栈内存的数组中,栈内存支持读写:
#include <stdio.h> #include <string.h> #if defined(_WIN32) #define SEPERATOR '\\' #elif defined(__unix__) || defined(__linux__) #define SEPERATOR '/' #endif int main(int argc, char *argv[]) { char path[] = "c/c/c/c/c"; // 字符串存储在栈上,允许修改 char *end = strrchr(path, SEPERATOR); // 增加判空,避免找不到分隔符时解引用NULL崩溃 if (end != NULL) { *end = '\0'; } printf("%s", path); return 0; }
方式2:动态分配堆内存
通过malloc在堆上分配内存并复制字符串,使用完记得释放内存:
#include <stdio.h> #include <string.h> #include <stdlib.h> #if defined(_WIN32) #define SEPERATOR '\\' #elif defined(__unix__) || defined(__linux__) #define SEPERATOR '/' #endif int main(int argc, char *argv[]) { const char *original = "c/c/c/c/c"; char *path = malloc(strlen(original) + 1); // 检查内存分配是否成功 if (path == NULL) { perror("malloc failed"); return 1; } strcpy(path, original); char *end = strrchr(path, SEPERATOR); if (end != NULL) { *end = '\0'; } printf("%s", path); free(path); // 释放堆内存,避免内存泄漏 return 0; }
额外注意点
- 必须加
end != NULL的判断:如果strrchr找不到指定分隔符,会返回NULL,直接解引用NULL会触发另一次段错误。
内容的提问来源于stack exchange,提问作者neo
相关产品推荐
相关产品推荐

