C语言字符串数组排序后出现垃圾字符的问题求助
问题分析与解决方法
核心问题1:访问已释放内存(野指针)
你在main函数里先释放了所有字符串的内存,再尝试打印这些已被释放的指针指向的内容:
// 先释放内存 for(i = 0; i < n;i++) free(list[i]); // 再访问已释放的指针,导致野指针 for(i = 0; i < n ;i++) printf("item %d is %s\n", i+1, list[i]);
内存被释放后,list[i]就变成了野指针,访问它的内容属于未定义行为,必然输出垃圾字符。
解决方法:调整顺序,先打印排序后的结果,再释放内存:
// 先打印排序后的结果 for(i = 0; i < n ;i++) printf("item %d is %s\n", i+1, list[i]); // 再释放内存 for(i = 0; i < n;i++) free(list[i]);
核心问题2:sortList函数排序逻辑错误
当前的sortList只做了一轮遍历,既不是完整的冒泡排序,还存在数组越界问题:
- 循环条件
for(i = 0; i < size; i++)会在i = size-1时访问ptr[i+1],也就是ptr[size],这超出了数组的有效范围(数组下标是0到size-1),会读取未知内存。 - 一轮遍历无法完成排序,冒泡排序需要多轮循环,每轮把最大的元素“冒泡”到末尾。
修正后的sortList函数:
void sortList(char *ptr[], int size) { int i, j; // 外层循环控制排序轮数,总共需要size-1轮 for(i = 0; i < size - 1; i++) { // 内层循环比较相邻元素,每轮减少i次比较(末尾i个元素已排序) for(j = 0 ; j < size - i - 1; j++) { if(strcmp(ptr[j], ptr[j+1]) > 0) swap(ptr, j, j+1); } } }
完整修正后的代码
#include<stdlib.h> #include<string.h> #include<stdio.h> #define SIZE 11 #define LEN 20 void sortList(char* ptr[], int size); void sortChars(char *str); void swap(char *a[], int c, int b); int main() { char *list[LEN]; int i, n; char input[SIZE+2]; printf("How many strings will you enter: "); scanf("%d", &n ); getchar(); //start reading strings if(n<=LEN) { for(i = 0; i< n;i++) { printf("Enter string %d: ",i+1); fgets(input, SIZE +2, stdin); input[strcspn(input,"\n")] = '\0'; list[i] = strdup(input); } } printf("\n原始输入:\n"); for(i = 0; i < n;i++) printf("item %d is %s\n", i+1 ,list[i]); printf("\n字符串内部字符排序后:\n"); for(i = 0; i<n;i++) { sortChars(list[i]); printf("item %d is %s\n",i+1, list[i]); } sortList(list, n); printf("\n数组整体排序后:\n"); // 先打印结果再释放内存 for(i = 0; i < n ;i++) printf("item %d is %s\n", i+1, list[i]); // 释放内存 for(i = 0; i < n;i++) free(list[i]); return 0; } void sortChars(char *str) { int i,j; int len = strlen(str); for(i = 0; i< len -1;i++) { for(j = 0 ;j<len-i-1;j++) { if(str[j]>str[j+1]) { char tem = str[j]; str[j] = str[j+1]; str[j+1]= tem; } } } } void sortList(char *ptr[], int size) { int i, j; for(i = 0; i < size - 1; i++) { for(j = 0 ; j < size - i - 1; j++) { if(strcmp(ptr[j], ptr[j+1]) > 0) swap(ptr, j, j+1); } } } void swap(char *ptra[], int a, int b) { char *temp = ptra[a]; ptra[a] = ptra[b]; ptra[b]= temp; }
运行示例(修正后)
How many strings will you enter: 2 Enter string 1: hello Enter string 2: world 原始输入: item 1 is hello item 2 is world 字符串内部字符排序后: item 1 is ehllo item 2 is dlorw 数组整体排序后: item 1 is dlorw item 2 is ehllo
内容的提问来源于stack exchange,提问作者nate998
相关产品推荐
相关产品推荐

