Linux下C语言Web客户端URL解析:硬编码字符串触发段错误
问题原因分析
你的代码出现段错误的核心原因是字符串常量的只读属性:
- 命令行传入的
argv[1]指向进程栈/堆中的可修改内存区域,执行*p = 0修改字符串内容是合法操作。 - 硬编码的
"http://github.com/"属于字符串常量,编译器会将这类数据放到程序的只读数据段(.rodata),尝试修改只读内存会直接触发内存访问错误,也就是段错误。
代码关键问题点
看parse_url函数中的这段代码:
if(p) { *p = 0; // 此处尝试修改字符串内容 p += 3; }
当传入硬编码字符串时,url指向的是只读内存,执行*p = 0就是在修改受保护的只读区域,直接引发段错误。
解决方案
要解决这个问题,需要把硬编码字符串复制到可修改的内存中再处理,两种常用方式:
方式1:用栈上的字符数组复制字符串
int main(int argc, char* argv[]) { parse_url(argv[1]); char url[] = "http://github.com/"; // 字符串常量被复制到栈数组,可修改 parse_url(url); }
方式2:用堆内存动态分配
#include <stdlib.h> int main(int argc, char* argv[]) { parse_url(argv[1]); const char* const_url = "http://github.com/"; char* url = malloc(strlen(const_url) + 1); // 分配足够内存 if (url) { strcpy(url, const_url); parse_url(url); free(url); // 记得释放堆内存 } }
补充说明
在C语言中,字符串字面量(如"abc")的类型是char*是历史遗留的兼容设计,实际上它不可修改,更严谨的写法应声明为const char*,这样编译器会在你尝试修改时直接抛出警告,提前避免运行时错误。
内容的提问来源于stack exchange,提问作者Jon Forhan
相关产品推荐
相关产品推荐

