C语言中通过指针对字符串执行数组式赋值为何会触发segfault?
段错误的根本原因
你遇到的崩溃完全是内存权限问题导致的,和字符串转换逻辑本身无关:
char *dna = "CCTAGGACCAGGTT"这行代码定义的指针,指向的是程序编译后存放在只读数据段的字符串字面量。这块内存被操作系统明确标记为不可写入,任何对这块地址的修改操作,哪怕是dna[0] = 'X'这种单字符赋值,都会直接触发内存访问违规,也就是你看到的segfault。- 你对指针操作的认知偏差,本质上是混淆了两类不同的内存对象:字符串指针只有指向栈上数组、堆申请内存这类可写区域时,才能通过下标/指针方式修改内容;指向字符串字面量的指针本身是只读的,完全不具备修改权限。
符合题目要求的修正方案
题目要求“既要修改输入原字符串、也要返回处理后的字符串”,仅需调整字符串的定义方式,让输入的字符串存放在可修改的内存区域即可,原有的转换逻辑不需要改动:
- 把main函数中定义dna的语句从
char *dna = "CCTAGGACCAGGTT"替换为char dna[] = "CCTAGGACCAGGTT"。这种写法会把字符串字面量的内容完整拷贝到栈上的可修改数组空间,后续对数组元素的修改是完全合法的。 - 原
rna函数的内部逻辑没有问题:函数内定义的char rna[len + 1]是栈上临时变量,因为你会在函数退出前把处理好的内容拷贝回dna,不存在栈空间回收后产生悬空指针的问题,完全可以支撑“修改原输入、返回处理后字符串”的题目要求。
修正后的可运行代码:
#include <stdio.h> #include <string.h> char* rna(char* dna) { size_t i, len = strlen(dna); char rna[len + 1]; rna[len] = '\0'; for(i = 0; i < len; i++){ char letter = dna[len - 1 - i]; if(letter == 'T') letter = 'U'; rna[i] = letter; } // 将处理后的内容写回原dna的可修改内存 for(i = 0; i < len; i++) dna[i] = rna[i]; return dna; } int main(void){ // 定义为栈上可修改数组,而非指向只读字面量的指针 char dna[] = "CCTAGGACCAGGTT"; printf("Input DNA: %s\nOutput RNA: %s\n", dna, rna(dna)); return 0; }
注意:如果后续调用
rna函数的外部代码传入的是char *p = "xxx"这类指向只读字面量的指针,哪怕main里的代码改对了,仍然会触发段错误。这类函数的形参约定中,通常会明确要求调用方传入的内存块必须是可修改、且大小足够容纳处理后内容的。
内容的提问来源于stack exchange,提问作者Korgan Rivera。
相关产品推荐
相关产品推荐

