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

C语言实现LeetCode字符频率排序时出现段错误求助

段错误原因分析:Sort Characters By Frequency 自定义实现问题

问题描述:用C语言解决LeetCode的「Sort Characters By Frequency」问题,要求给定字符串按字符出现频率降序排序返回结果(多答案时返回任意一个即可)。自行实现的方案运行时出现段错误,错误出现在两处标记的修改输入字符串位置,假设输入均为大写字母,代码如下:

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

char *frequencySort(char *s)
{
    int strlenn = strlen(s);

    int fq[strlenn];

    // init with 1 because at least 1 time char occur in input str.
    for (int i = 0; i < strlenn; i++)
    {
        fq[i] = 1;
    }
    // count freq of string and replace dublicate char with *
    // ex: ABCDA => ABCD*
    for (int i = 0; i < strlenn - 1; i++)
    {
        if (s[i] == '*')
        {
            continue;
        }

        for (int j = (i + 1); j < strlenn; j++)
        {
            if (s[i] == s[j])
            {
                fq[i]++;
                s[j] = (char)'*';  // segmentation violation error shows here
                fq[j] = 0;
            }
        }
    }

    
    // sort freqency by in decending order and str char
    // ex: ABCDDDAA =  freq[3, 3, 1, 1] =  soredt str = [ A, D, B, C ]
    for (int i = 0; i < strlenn - 1; i++)
    {
        for (int j = i + 1; j < strlenn; j++)
        {
            if (fq[i] < fq[j])
            {
                // swap
                int temp = fq[i];
                fq[i] = fq[j];
                fq[j] = temp;

                // swap string char
                char temp1 = s[i];
                s[i] = s[j]; // segmentation violation error shows here
                s[j] = temp1;
            }
        }
    }
    char *result = (char *)calloc(strlenn + 1, sizeof(char));
    int l = 0;
    for (int i = 0; fq[i] != 0 && i < strlenn; i++)
    {
        int k = fq[i];

        while (k > 0)
        {
            printf("%c", s[i]);
            result[l++] = s[i];
            k--;
        }
    }
    result[l] = '\0';
    return result;
}

int main()
{

    char *s = "ABCDDDAA";
    frequencySort(s);

    return 0;
}

段错误核心原因

  • 试图修改只读内存中的字符串常量
    在main函数中,char *s = "ABCDDDAA";定义的是字符串常量,这类常量被存储在程序的只读数据段(.rodata),操作系统会禁止对该区域的写操作。代码中两处错误位置:
    1. s[j] = (char)'*';:将重复字符替换为*,属于写只读内存操作
    2. s[i] = s[j];:排序交换字符时,同样修改了只读内存
      这两种操作都会触发内存访问违规,直接导致段错误。

修复方案

  1. 将字符串常量转为可修改的字符数组
    修改main函数中的字符串定义为:

    char s[] = "ABCDDDAA";
    

    此时字符串存储在栈内存中,属于可修改区域,能正常执行后续的字符修改操作。

  2. 补充优化(可选)

    • 局部变长数组int fq[strlenn];如果遇到过长的输入字符串,可能导致栈溢出,建议改用动态内存分配:
      int *fq = malloc(strlenn * sizeof(int));
      // 使用完毕后记得释放内存:free(fq);
      

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 19:10:29