C语言中char*指针赋值单个字符触发段错误的原因排查
问题根源:字符串字面量的只读属性与内存存储差异
咱们把你的代码问题拆成两部分说,段错误的核心原因和一个容易忽略的小语法问题:
1. 段错误的核心原因:只读数据段的字符串字面量
你写的 char *ptr = "abcdefghijklm"; 里,"abcdefghijklm" 是字符串字面量。在C语言里,这类字面量会被编译器放在程序的只读数据段(比如常见的.rodata段)中,这块内存是受系统保护的,不允许程序进行写入操作。
虽然C语言允许你用非const的char*指针指向它(这是历史遗留的语法兼容),但本质上这个指针指向的是只读内存。当你尝试执行ptr[2] = ...修改这块内存时,就触发了内存访问违规,系统直接抛出段错误(Segmentation Fault)。
而当你改成char ptr[32] = "abcdefghijklm";时,情况完全不同:编译器会在栈上分配一块32字节的可读写内存,然后把字符串字面量的内容拷贝到这个数组里。你修改的是栈上的可读写内存,自然不会有问题。
2. 代码里的另一个小错误
你写的ptr[2] = "q";还有个语法问题:右边的"q"是字符串字面量,它的类型是char*,而左边的ptr[2]是单个char类型,类型不匹配。正确的写法应该是用单引号包裹字符字面量:ptr[2] = 'q';。不过这个错误本身不会导致段错误,但会让编译器报错或者产生未定义行为。
总结一下正确的写法
如果需要修改字符串内容,要么用数组:
int main () { char ptr[32] = "abcdefghijklm"; ptr[2] = 'q'; printf("%s",ptr); return 0; }
要么用动态分配的可读写内存:
#include <stdlib.h> #include <string.h> int main () { char *ptr = malloc(strlen("abcdefghijklm") + 1); if (ptr == NULL) { // 处理内存分配失败的情况 return 1; } strcpy(ptr, "abcdefghijklm"); ptr[2] = 'q'; printf("%s",ptr); free(ptr); // 记得释放动态内存 return 0; }
内容的提问来源于stack exchange,提问作者Yashwanth Manjegowda
相关产品推荐
相关产品推荐

