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),操作系统会禁止对该区域的写操作。代码中两处错误位置:s[j] = (char)'*';:将重复字符替换为*,属于写只读内存操作s[i] = s[j];:排序交换字符时,同样修改了只读内存
这两种操作都会触发内存访问违规,直接导致段错误。
修复方案
将字符串常量转为可修改的字符数组
修改main函数中的字符串定义为:char s[] = "ABCDDDAA";此时字符串存储在栈内存中,属于可修改区域,能正常执行后续的字符修改操作。
补充优化(可选)
- 局部变长数组
int fq[strlenn];如果遇到过长的输入字符串,可能导致栈溢出,建议改用动态内存分配:int *fq = malloc(strlenn * sizeof(int)); // 使用完毕后记得释放内存:free(fq);
- 局部变长数组
内容的提问来源于stack exchange,提问作者horsemann07
相关产品推荐
相关产品推荐

