将char数组改为char*后出现段错误的原因及解决方法咨询
为什么用
char*替换数组后strtok会触发段错误?正确的指针版本怎么写?段错误会损坏磁盘数据吗? 先解决段错误的问题
你遇到的段错误核心原因很明确:当你写char *string = "Test,string1,Test,string2:Test:string3";时,string指向的是字符串常量,它被存储在程序的只读内存区域(比如Linux里的.rodata段)。而strtok的工作逻辑是直接修改原字符串——它会把找到的分隔符替换成'\0'来分割出token,这就相当于往只读内存里写数据,操作系统自然会触发内存访问违规,也就是段错误。
下面给你几种正确的指针版本实现方式:
方式一:动态分配可写内存并复制字符串
通过malloc申请一块可写内存,把字符串常量复制进去再操作,用完记得释放内存避免泄漏:
#include <stdio.h> #include <string.h> #include <stdlib.h> int main () { const char *original_str = "Test,string1,Test,string2:Test:string3"; // 申请足够内存,+1是为了存末尾的'\0' char *string = malloc(strlen(original_str) + 1); if (string == NULL) { // 必须检查malloc是否成功 perror("malloc failed"); return 1; } strcpy(string, original_str); // 复制到可写内存 char *p; printf ("String \"%s\" is split into tokens:\n", string); p = strtok (string, ",:"); while (p!= NULL) { printf ("%s\n", p); p = strtok (NULL, ",:"); } free(string); // 释放内存 return 0; }
方式二:用strdup简化复制(POSIX环境可用)
如果你的系统支持POSIX标准(比如Linux、macOS),可以用strdup函数,它会自动完成malloc+strcpy的操作,代码更简洁:
#include <stdio.h> #include <string.h> #include <stdlib.h> int main () { char *string = strdup("Test,string1,Test,string2:Test:string3"); if (string == NULL) { perror("strdup failed"); return 1; } char *p; printf ("String \"%s\" is split into tokens:\n", string); p = strtok (string, ",:"); while (p!= NULL) { printf ("%s\n", p); p = strtok (NULL, ",:"); } free(string); return 0; }
方式三:指针指向栈上的可写数组
如果不想用动态内存,也可以先定义栈上的可写数组,再让指针指向它,本质还是利用可写内存:
#include <stdio.h> #include <string.h> int main () { char buf[100] = "Test,string1,Test,string2:Test:string3"; char *string = buf; // 指针指向可写的栈内存 char *p; printf ("String \"%s\" is split into tokens:\n", string); p = strtok (string, ",:"); while (p!= NULL) { printf ("%s\n", p); p = strtok (NULL, ",:"); } return 0; }
关于段错误是否会损坏磁盘数据
完全不会。段错误是进程试图访问不属于自己的内存,或者往只读内存写数据时,操作系统终止进程的行为,全程发生在内存层面,不会直接损坏磁盘上已有的数据。
只有一种特殊情况需要注意:如果你的进程正在往磁盘文件写数据时触发了段错误,可能会导致正在写入的文件出现不完整的内容,但这不是“损坏”——只是写入过程被中断,磁盘上原本存在的其他数据不会受影响,而且这是进程中断导致的写入不完整,不是段错误本身直接造成的磁盘损坏。
内容的提问来源于stack exchange,提问作者rnso
相关产品推荐
相关产品推荐

