通用void指针地址交换函数异常:字符串交换仅函数内生效
问题:通用swap函数无法正确交换字符串指针的外部值
你编写了一个意图支持任意类型指针交换的swap函数,实现代码如下:
void swap(void* x,void* y){ void* temp=x; x=y; y=temp; }
该函数处理整数时看似正常,但处理字符串指针时,仅在函数内部可见地址交换,外部调用后原数组中的指针地址并未改变。
调用代码及调试过程
调用swap的代码片段:
printf("before %s %s\n",(char*)array[i],(char*)array[j] ); swap(array[i], array[j]); printf("after %s %s\n",(char*)array[i],(char*)array[j] );
为排查问题,你给swap函数添加了调试输出:
void swap(void* x,void* y){ printf(" after IN %s %s\n",(char*)x,(char*)y ); void* temp=x; x=y; y=temp; printf(" after IN %s %s\n",(char*)x,(char*)y ); }
得到的输出结果:
before fannullone falafel after IN fannullone falafel after IN falafel fannullone after fannullone falafel
问题根源
你的swap函数陷入了C语言传值调用的典型误区:你交换的是函数形参的副本,而非外部实参本身。
当调用swap(array[i], array[j])时,array[i]和array[j]的值(即字符串的内存地址)会被拷贝到函数的形参x和y中。函数内部交换的只是这两个拷贝的地址,外部的array[i]和array[j]完全没有被修改。
你觉得处理整数时“正常”,大概率是当时传递的是整数变量的地址,且在函数内部通过解引用交换了变量内容;但现在你要交换的是指针本身(字符串指针),此时必须传递指针的指针(即void**)才能修改外部的指针变量。
正确实现方案
方案1:通用型swap(支持任意类型)
要实现真正通用的swap函数,需要接收指针的指针作为参数,同时传入要交换的数据大小(因为void*无法直接解引用),通过内存拷贝完成交换:
#include <stdlib.h> #include <string.h> void swap(void* x, void* y, size_t size) { // 分配临时内存存储数据 void* temp = malloc(size); if (temp == NULL) { // 内存分配失败,直接返回 return; } // 拷贝数据完成交换 memcpy(temp, x, size); memcpy(x, y, size); memcpy(y, temp, size); // 释放临时内存 free(temp); }
调用示例(交换字符串指针数组中的元素):
printf("before %s %s\n", array[i], array[j]); swap(&array[i], &array[j], sizeof(char*)); printf("after %s %s\n", array[i], array[j]);
调用示例(交换整数变量):
int a = 10, b = 20; swap(&a, &b, sizeof(int));
方案2:针对指针交换的简化实现
如果你的场景仅需交换指针(如字符串指针),可以直接编写接收void**的函数,无需传递数据大小:
void swap_ptr(void** x, void** y) { void* temp = *x; *x = *y; *y = temp; }
调用示例:
swap_ptr((void**)&array[i], (void**)&array[j]);
内容的提问来源于stack exchange,提问作者ramaswag
相关产品推荐
相关产品推荐

