使用指针交换数组出错:为何无法实现完整数组交换?
问题分析与解决:数组交换的错误原因及修正方案
核心错误原因
1. 数组名是不可修改的常量,不能直接修改其"指向"
你代码里的arr1和arr2是数组类型,不是指针变量。虽然数组名在表达式中会隐式转换成指向首元素的指针,但它本身是一个不可修改的左值(可以理解成只读的"指针常量")。你强制通过(int**)&arr1把数组名的地址传给swap函数,试图修改arr1的"指向",这属于未定义行为——编译器不会阻止你,但实际运行时会破坏栈上的内存布局,这就是你看到前两个元素交换、后面元素不变的诡异输出的原因。
2. 无用的malloc导致内存泄漏
swap函数里你用malloc分配了内存给temp,但紧接着就把temp赋值为*a,之前malloc的内存地址直接丢失,永远无法释放,造成了内存泄漏。这块malloc完全是多余的。
正确的解决方案
根据你的需求,有两种可行的解决方式:
方式一:交换数组的所有元素(保持原数组内存位置不变)
如果你需要让arr1和arr2所在的内存位置里的内容完全交换,直接遍历交换每个元素即可:
#include <stdio.h> // 交换两个数组的元素内容 void swap_arrays(int *a, int *b, int size) { for (int i = 0; i < size; i++) { int temp = a[i]; a[i] = b[i]; b[i] = temp; } } int main() { int arr1[] = {1, 2, 3, 4, 5}; int arr2[] = {6, 7, 8, 9, 10}; const int size = sizeof(arr1) / sizeof(arr1[0]); // 自动计算数组长度 swap_arrays(arr1, arr2, size); for(int i=0; i<size; i++) printf("%d\t", arr1[i]); printf("\n"); for(int i=0; i<size; i++) printf("%d\t", arr2[i]); printf("\n"); return 0; }
方式二:用指针变量指向数组,交换指针的指向
如果你不需要修改原数组内存的内容,只是想让某个指针指向另一个数组的内容,可以用指针变量来操作:
#include <stdio.h> // 交换两个指针变量的指向 void swap_pointers(int **a, int **b) { int *temp = *a; *a = *b; *b = temp; } int main() { int arr1[] = {1, 2, 3, 4, 5}; int arr2[] = {6, 7, 8, 9, 10}; int *p1 = arr1; // 指针变量指向arr1首元素 int *p2 = arr2; // 指针变量指向arr2首元素 const int size = sizeof(arr1) / sizeof(arr1[0]); swap_pointers(&p1, &p2); // 传递指针变量的地址 // 通过指针访问数组内容 for(int i=0; i<size; i++) printf("%d\t", p1[i]); printf("\n"); for(int i=0; i<size; i++) printf("%d\t", p2[i]); printf("\n"); return 0; }
总结
- 永远不要试图修改数组名的"指向",数组名是常量,不是可赋值的指针变量。
- 按需选择方案:要交换内存内容就用元素遍历交换;要切换指向就用指针变量操作。
- 避免无用的内存分配,malloc的内存必须记得释放,否则会造成泄漏。
内容的提问来源于stack exchange,提问作者theunixdisaster
相关产品推荐
相关产品推荐

