You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何对赋值为字符串字面量的malloc指针调用strtok会触发总线错误

问题原因分析
  • 指针指向错误,触发非法写操作
    你最初通过malloc给str申请了16字节的可写堆内存,但后续执行str = "This - is - foo";时,并没有把字符串内容写入这块堆内存,而是直接修改了str指针的指向,让它指向了双引号包裹的字符串常量。C语言中的字符串常量存储在进程的只读数据段,该区域内存没有写权限。
  • strtok的运行逻辑需要修改原字符串
    strtok做字符串分割时,会直接在原字符串的分隔符位置写入\0来截断字符串,当传入的指针指向只读内存时,这个写操作就会触发总线错误/段错误。
  • 额外问题:内存泄漏
    修改str的指向后,原本malloc申请的16字节内存再也没有指针可以访问,会造成内存泄漏。
修复方案

有两种常用的修复方式:

方案1:将字符串内容拷贝到可写堆内存

把直接赋值的str = "This - is - foo";替换为strcpy(str, "This - is - foo");,将字符串常量的内容拷贝到之前malloc申请的可写堆空间中即可。
修复后的完整代码:

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

int main () {
   char *str = malloc(16);
   memset(str, '\0', 16);
   // 用strcpy拷贝内容,而非修改指针指向
   strcpy(str, "This - is - foo");

   const char s[2] = "-";
   char *token;
   
   /* 获取第一个分割片段 */
   token = strtok(str, s);
   
   /* 遍历剩余分割片段 */
   while( token != NULL ) {
      printf( " %s\n", token );
    
      token = strtok(NULL, s);
   }
   // 手动释放堆内存避免泄漏
   free(str);
   
   return(0);
}

方案2:直接用栈数组存储字符串

如果不需要动态申请内存,可以直接定义栈上的字符数组存储字符串,栈内存默认可写,也可以正常运行:

#include <string.h>
#include <stdio.h>

int main () {
   // 数组存储的字符串是可写的
   char str[] = "This - is - foo";
   const char s[2] = "-";
   char *token;
   
   token = strtok(str, s);
   while( token != NULL ) {
      printf( " %s\n", token );
      token = strtok(NULL, s);
   }
   
   return 0;
}

内容的提问来源于stack exchange,提问作者Lucky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 10:45:03