字符数组调用qsort出现段错误,求问题定位与解决
调用qsort排序字符串常量触发段错误的原因及修复方案
问题根源
你传递给qsort的是字符串字面量(代码中用双引号直接定义的字符串,比如"abvasfa"),这类字符串在程序运行时存储在只读数据段(如Linux下的.rodata)中。qsort排序时会修改数组元素的内存位置,尝试写入只读内存会直接触发段错误(内存访问违规)。
你的代码里,main函数传入的"abvasfa"和"avbasda"是const char*类型的常量,但checkPermutation_sort的参数声明为char*,编译器可能不会强制报错,但运行时修改只读内存的行为是C标准定义的未定义行为,必然导致崩溃。
修复方案
核心思路:不要直接对字符串常量调用qsort,先将字符串复制到可修改的内存区域(栈数组或堆内存),再对副本排序。
方案1:使用堆内存分配副本(通用场景)
#include<stdio.h> #include<stdlib.h> #include<string.h> int cmpfnc (const void *a, const void *b) { return *(const char *)a - *(const char *)b; } int checkPermutation_sort (const char *s1, const char *s2) { int l1 = strlen(s1); int l2 = strlen(s2); if (l1 != l2) return -1; // 分配可修改的内存副本 char *copy1 = malloc(l1 + 1); char *copy2 = malloc(l2 + 1); if (!copy1 || !copy2) { free(copy1); free(copy2); return -1; // 内存分配失败处理 } strcpy(copy1, s1); strcpy(copy2, s2); // 对副本排序 qsort(copy1, l1, sizeof(char), cmpfnc); qsort(copy2, l2, sizeof(char), cmpfnc); // 比较结果 int result = strcmp(copy1, copy2); // 释放堆内存 free(copy1); free(copy2); return result; } int main () { printf("%d\n", checkPermutation_sort("abvasfa", "avbasda")); return 0; }
方案2:使用栈数组(适合字符串长度较小且固定的场景)
如果能确定输入字符串的最大长度,用栈数组更高效,无需手动管理内存:
#include<stdio.h> #include<stdlib.h> #include<string.h> int cmpfnc (const void *a, const void *b) { return *(const char *)a - *(const char *)b; } int checkPermutation_sort (const char *s1, const char *s2) { int l1 = strlen(s1); int l2 = strlen(s2); if (l1 != l2) return -1; // 栈数组存储副本(假设字符串长度不超过99) char copy1[100], copy2[100]; strcpy(copy1, s1); strcpy(copy2, s2); qsort(copy1, l1, sizeof(char), cmpfnc); qsort(copy2, l2, sizeof(char), cmpfnc); return strcmp(copy1, copy2); } int main () { printf("%d\n", checkPermutation_sort("abvasfa", "avbasda")); return 0; }
补充说明
从你提供的gdb调试信息可以看到,s1的地址是0x55555555600c,这个地址属于程序的只读数据区。当qsort内部执行memmove等操作尝试修改该区域内存时,就会触发段错误,这和我们分析的原因完全吻合。
内容的提问来源于stack exchange,提问作者Aliasgar Musani
相关产品推荐
相关产品推荐

