C语言通用swap函数可交换字符串,交换数组触发核心转储问题
为什么通用swap函数能交换字符串指针却无法交换数组?
你的问题核心在于混淆了字符串指针和数组名的本质差异,下面拆解问题原因并给出解决方案:
1. 字符串指针交换能正常工作的原因
你定义的char *h = "hell"和char *w = "world"中,h和w是指针变量——它们在栈上拥有自己的存储空间,存储的是字符串常量的首地址。
当你调用swap((void **)&h, (void **)&w)时:
&h是指针变量h的地址,类型为char **,强制转为void **后传入swap函数是合法的- swap函数内部交换的是
*a和*b,也就是两个指针变量中存储的地址值,本质是修改指针变量的内容,完全符合内存规则,所以能正常运行。
2. 数组交换触发栈崩溃的原因
而char c[5]和char d[3]中的c和d是数组名,它不是可修改的变量,而是一个编译期的常量标识符,代表数组首元素的地址。
当你执行swap((void **)&c, (void **)&d)时:
&c的实际类型是char (*)[5](指向长度为5的char数组的指针),你强行将其转为void **是类型不匹配的错误转换- swap函数内部的
*a = tmp操作,本质是试图给数组名c赋值——但数组名是固定的常量,它的地址对应栈上的固定区域,修改这个区域会直接破坏栈结构,触发栈溢出检测(stack smashing detected),最终导致程序崩溃。
简单说:数组名不是指针变量,你不能给它赋值,自然无法通过交换指针的方式"交换数组"。
3. 正确的数组交换方案
如果你想实现类似"交换数组"的效果,有两种可行方式:
方式一:用指针变量存储数组地址,交换指针变量
把数组的首地址存入指针变量,再交换指针变量,这样和字符串指针的逻辑一致:
int main() { // ... 字符串交换部分不变 ... char c[5] = { 'a', 'e', 'i', 'o', 'u' }; char d[3] = { '1', '2', '3' }; // 定义指针变量存储数组首地址 char *pc = c; char *pd = d; print_array(pc, 5); print_array(pd, 3); swap((void **)&pc, (void **)&pd); // 交换后pc指向d的首地址,pd指向c的首地址 print_array(pc, 3); // 输出:1 2 3 print_array(pd, 5); // 输出:a e i o u return 0; }
方式二:真正交换数组的内容(而非指针)
如果需要交换两个数组的实际元素,需要编写一个基于内存拷贝的通用交换函数,传入元素大小和数组长度:
#include "stdio.h" #include "string.h" // 交换两个数组的内容 void swap_arrays(void *a, void *b, size_t elem_size, size_t count) { size_t total_size = elem_size * count; // 临时缓冲区存储数据 unsigned char tmp[total_size]; memcpy(tmp, a, total_size); memcpy(a, b, total_size); memcpy(b, tmp, total_size); } void print_array(char *c, int size) { for (int i = 0; i < size; ++i) { printf("%c ", c[i]); } printf("\n"); } int main() { char c[5] = { 'a', 'e', 'i', 'o', 'u' }; char d[5] = { '1', '2', '3', '4', '5' }; // 注意数组长度要一致,或取较小的长度 print_array(c, 5); print_array(d, 5); // 交换前3个元素 swap_arrays(c, d, sizeof(char), 3); print_array(c, 5); // 输出:1 2 3 o u print_array(d, 5); // 输出:a e i 4 5 return 0; }
关键总结
- 字符串指针是可修改的变量,存储的是字符串的地址,交换的是地址值。
- 数组名是编译期常量,不是变量,它仅代表数组首元素的地址,无法被赋值。
- 强行将数组指针转为
void **修改会触发未定义行为,导致栈崩溃。
内容的提问来源于stack exchange,提问作者Der Fänger im Roggen
相关产品推荐
相关产品推荐

