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

使用strsep分割字符串存储时触发段错误的问题排查

问题分析与解决方案

段错误的核心原因

你的代码存在两个关键问题:

  • 未初始化的指针判断:found变量在第一次循环前没有赋值,直接用while(found!=NULL)做判断,这属于未定义行为,大概率是触发段错误的根源。
  • 循环逻辑倒置:strsep的正确使用流程应该是先调用函数获取分割结果,再判断结果是否为NULL,而非先判断未初始化的指针。

另外,当前写法还存在潜在风险:strsep返回的指针指向strdup分配的临时内存temp,如果后续释放temp,result数组里的所有指针都会变成悬空指针,访问它们会触发未定义行为。

修正后的代码

方式一:临时内存复用(需注意内存释放时机)

如果只是临时使用分割后的单词,不需要持久化,可以保留strdup的临时内存,修正循环逻辑即可:

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

void messtowords(char* string, char** result) {
    char* temp = strdup(string);
    if (temp == NULL) { // 检查内存分配是否成功
        *result = NULL;
        return;
    }
    char* del = " ";
    int i = 0;
    char* in = temp;
    char* found;

    // 先调用strsep获取结果,再判断是否继续循环
    while ((found = strsep(&in, del)) != NULL) {
        // 跳过连续空格产生的空字符串
        if (*found != '\0') {
            result[i] = found;
            i++;
        }
    }
    result[i] = NULL; // 用NULL标记数组末尾,方便后续遍历
}

int main(void) {
    char TC_norep[] = "This is a test string";
    char* words[100];
    messtowords(TC_norep, words);
    
    // 遍历打印所有单词
    for (int j = 0; words[j] != NULL; j++) {
        printf("%s\n", words[j]);
    }

    // 所有words指针都指向同一块临时内存,释放一次即可
    free(words[0]);
    return 0;
}

方式二:持久化存储单词(避免悬空指针)

如果需要长期保存分割后的单词,应该为每个单词单独分配内存,避免临时内存释放后指针失效:

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

void messtowords(char* string, char** result) {
    char* temp = strdup(string);
    if (temp == NULL) {
        *result = NULL;
        return;
    }
    char* del = " ";
    int i = 0;
    char* in = temp;
    char* found;

    while ((found = strsep(&in, del)) != NULL) {
        if (*found != '\0') {
            // 为每个单词分配独立内存并复制内容
            result[i] = strdup(found);
            i++;
        }
    }
    result[i] = NULL;

    free(temp); // 临时内存可安全释放
}

int main(void) {
    char TC_norep[] = "This is a test string";
    char* words[100];
    messtowords(TC_norep, words);
    
    for (int j = 0; words[j] != NULL; j++) {
        printf("%s\n", words[j]);
        free(words[j]); // 每个单词单独释放内存
    }
    return 0;
}

关于字符指针数组的修改问题

你在main里定义的char* words[100]是栈上的指针数组,每个元素都是可修改的char*类型指针。之前的段错误并非因为无法修改数组元素,而是未初始化指针的非法判断引发的未定义行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 06:23:25