C语言生成字母数字字符串并排序的指针使用问题求助
代码问题分析与修正
你的代码存在多处指针使用错误、逻辑漏洞和内存管理问题,下面逐个拆解并给出修正方案:
核心错误点梳理
1. 二级指针未初始化(main函数)
char** str; **str=*randomString(minSize,maxSize);
char** str是未初始化的野指针,直接解引用**str会触发程序崩溃;- 正确做法:先为指针数组分配内存,再逐个生成字符串并赋值给数组元素。
2. sort函数逻辑完全错误
sortedArray未分配内存,直接赋值会导致未定义行为;- 循环变量错误:内层循环误用
++i而非++j,导致外层循环提前终止; - 类型不匹配:
strArray[i]是char*类型(字符串指针),和j(char类型)比较毫无意义; - 未实现字符串排序的核心逻辑(比如按字典序比较)。
3. 其他细节问题
printStrings里的换行符写错:printf("/n");应为printf("\n");;randomString未初始化随机种子,每次运行生成的字符串完全相同;- 未实现字母数字字符串生成(当前仅生成小写字母);
- 未释放动态分配的内存,存在内存泄漏。
修正后的完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> // 定义字母数字字符范围:数字0-9,小写a-z,大写A-Z #define NUM_START '0' #define NUM_END '9' #define LOWER_START 'a' #define LOWER_END 'z' #define UPPER_START 'A' #define UPPER_END 'Z' #define NULL_CHAR '\0' // 生成指定长度范围的字母数字随机字符串 char *randomString(int minSize, int maxSize) { int i, strSize; char *newStr; // 初始化随机种子(仅执行一次) static int seed_init = 0; if (!seed_init) { srand((unsigned int)time(NULL)); seed_init = 1; } strSize = minSize + (rand() % (maxSize - minSize + 1)); newStr = (char*)malloc(strSize + 1); if (newStr == NULL) { printf("\n内存分配失败,无法生成随机字符串。\n"); return NULL; } for (i = 0; i < strSize; i++) { // 随机选择字符类型:数字、小写、大写 int type = rand() % 3; switch (type) { case 0: newStr[i] = NUM_START + (rand() % (NUM_END - NUM_START + 1)); break; case 1: newStr[i] = LOWER_START + (rand() % (LOWER_END - LOWER_START + 1)); break; case 2: newStr[i] = UPPER_START + (rand() % (UPPER_END - UPPER_START + 1)); break; } } newStr[i] = NULL_CHAR; return newStr; } // 打印字符串数组,每个字符串换行显示 void printStrings(char **strArray, int strArraySize) { int i; for (i = 0; i < strArraySize; ++i) { printf("%s\n", strArray[i]); } printf("\n"); } // 对字符串数组按字典序排序(冒泡排序,适合小规模数组) void sortStrings(char **strArray, int strArraySize) { int i, j; // 直接交换指针,无需复制字符串,效率更高 for (i = 0; i < strArraySize - 1; ++i) { for (j = 0; j < strArraySize - i - 1; ++j) { // 使用strcmp比较两个字符串的字典序 if (strcmp(strArray[j], strArray[j+1]) > 0) { char *temp = strArray[j]; strArray[j] = strArray[j+1]; strArray[j+1] = temp; } } } } // 释放字符串数组的内存 void freeStrings(char **strArray, int strArraySize) { int i; for (i = 0; i < strArraySize; ++i) { free(strArray[i]); } free(strArray); } int main() { int size, minSize = 5, maxSize = 20; char **strArray; printf("请输入要生成的字符串数量:\n"); // 检查输入有效性 if (scanf("%d", &size) != 1 || size <= 0) { printf("输入无效,请输入正整数。\n"); return 1; } // 为指针数组分配内存:每个元素是char*类型 strArray = (char**)malloc(size * sizeof(char*)); if (strArray == NULL) { printf("\n内存分配失败,无法创建字符串数组。\n"); return 1; } // 逐个生成字符串并赋值 for (int i = 0; i < size; ++i) { strArray[i] = randomString(minSize, maxSize); if (strArray[i] == NULL) { // 生成失败时释放已分配的内存 freeStrings(strArray, i); return 1; } } printf("生成的字符串列表:\n"); printStrings(strArray, size); printf("排序后的字符串列表:\n"); sortStrings(strArray, size); printStrings(strArray, size); // 释放所有动态分配的内存 freeStrings(strArray, size); return 0; }
关键知识点讲解
1. 字符串与指针的关系
- C语言中,字符串是
char*类型指针,指向以'\0'结尾的字符数组; - 字符串数组是
char**类型:数组的每个元素是char*(指向一个字符串); - 分配内存时,字符串需额外多留1字节存储
'\0',指针数组需分配元素数量 * sizeof(char*)的内存。
2. 字符串排序的正确方式
- 用
strcmp函数比较字符串字典序:strcmp(a, b) < 0:a在字典序中排在b前;strcmp(a, b) == 0:a和b相等;strcmp(a, b) > 0:a在字典序中排在b后;
- 排序时直接交换字符串指针,比复制整个字符串效率更高。
3. 内存管理要点
- 动态分配的内存必须用
free释放,避免内存泄漏; - 分配内存后必须检查返回值是否为
NULL,判断分配是否成功; - 程序中途出错时,要释放已分配的内存,避免资源浪费。
4. 随机数生成注意事项
- 使用
rand()前必须调用srand(time(NULL))初始化随机种子,否则每次运行生成的随机序列完全相同; - 用
static变量确保种子只初始化一次,避免多次调用randomString时重复初始化。
内容的提问来源于stack exchange,提问作者dannyph
相关产品推荐
相关产品推荐

