strtok触发Core Dump:字符串指针与数组的差异解析
为什么使用字符串字面量调用strtok会触发Core Dump?
这问题戳中了C语言里字符串字面量和字符数组的关键区别,以及strtok的核心工作特性,我给你一步步拆解:
1. 字符串字面量 vs 字符数组的内存属性
- 当你写
char *b = "ls -l";时,"ls -l"是字符串字面量,编译器会把它放在程序的只读数据段(比如Linux的.rodata)。指针b指向的是这块只读内存的起始地址,任何修改这块内存的操作都是未定义行为,操作系统会直接拦截并触发段错误(也就是你看到的Core Dump)。 - 而
char b[] = "ls -l";是把字符串字面量的内容完整拷贝到了栈上的字符数组中,栈内存属于可读写区域,你可以自由修改数组里的内容,不会有内存访问限制。
2. strtok的工作原理:它会修改原字符串
虽然strtok的函数签名里第一个参数是char*,但它的功能实现依赖于修改传入的字符串:
strtok会扫描字符串,找到你指定的分隔符(这里是空格
或制表符\t),然后把这个分隔符替换成'\0',以此分割出第一个token;同时它会在内部保存下一个要处理的位置,方便后续调用strtok(NULL, ...)继续分割。
这就意味着,strtok要求传入的char*必须指向可写的内存区域——如果传入的是只读内存(比如字符串字面量的指针),strtok尝试修改分隔符为'\0'时,就会触发内存访问错误,直接Core Dump。
3. 回到你的代码验证
- 用
char *b = "ls -l";时,strtok试图修改只读内存里的空格,触发段错误; - 改成
char b[] = "ls -l";后,b指向栈上的可写数组,strtok修改分隔符的操作合法,代码正常运行。
额外提一句:C语言里允许用char*指向字符串字面量是历史遗留特性,但这绝不意味着你可以修改它——这种写法现在其实不推荐,更安全的写法是const char* b = "ls -l";,这样编译器会在你尝试修改时直接报错,提前避免问题。
内容的提问来源于stack exchange,提问作者xmc
相关产品推荐
相关产品推荐

