如何避免C语言选择排序函数修改原输入变量key?
问题分析与解决方法
首先明确:你用的string是CS50定义的类型,本质就是char*。当前问题的核心是指针传递的特性——你把key传给selectionSort时,传递的是指针的副本,但这个副本仍然指向原key(也就是argv[1])的内存区域,所以函数里对arr的修改,直接改动了原内存的内容,自然会影响main里的key。
你之前尝试复制key但失败,大概率是只复制了指针(比如string copy = key;),这根本没复制字符串内容,copy和key还是指向同一块内存;如果加了const,编译器会直接报错,因为selectionSort要修改传入的字符串,无法接收const类型的指针。
正确解决步骤
- 在
main里为原字符串创建独立的内存副本,把原key的内容复制到新内存中 - 把这个副本传给排序函数,排序时只会修改副本,原
key完全不受影响 - 用完副本后记得释放内存,避免内存泄漏
修改后的完整代码
#include <ctype.h> #include <stdio.h> #include <string.h> #include <stdlib.h> // 引入malloc和free的头文件 int get_index(char c); string selectionSort(string arr, int n); int main(int argc, string argv[]) { // 先校验命令行参数是否正确传入 if (argc != 2) { printf("Usage: ./program key\n"); return 1; } string key = argv[1]; int str_len = strlen(key); // 1. 分配新内存,长度+1是为了存储字符串末尾的'\0'终止符 string key_copy = malloc(str_len + 1); // 检查内存分配是否成功 if (key_copy == NULL) { printf("Memory allocation failed\n"); return 1; } // 2. 将原key的内容复制到新内存中 strcpy(key_copy, key); // 3. 传入副本进行排序,原key不会被修改 string sorted = selectionSort(key_copy, str_len); // 可添加打印逻辑验证结果 printf("Original key: %s\n", key); printf("Sorted key: %s\n", sorted); // 4. 释放内存,避免内存泄漏 free(key_copy); return 0; } string selectionSort(string arr, int n) { int i, j, min_idx; for (i = 0; i < n - 1; i++) { min_idx = i; for (j = i + 1; j < n; j++) { if (arr[j] < arr[min_idx]) { min_idx = j; } } // 交换元素 char x = arr[min_idx]; arr[min_idx] = arr[i]; arr[i] = x; } return arr; }
额外说明
- 为什么要
malloc(str_len + 1)?因为C语言字符串以'\0'结尾,strlen只计算有效字符长度,不包含这个终止符,所以分配内存时必须多留一个字节存储它。 - 必须检查
malloc的返回值,如果内存分配失败,malloc会返回NULL,不处理会导致后续操作崩溃。 - 排序函数无需修改,只要传入独立副本,原字符串就不会被改动。
内容的提问来源于stack exchange,提问作者Miqueler
相关产品推荐
相关产品推荐

