我正在尝试编写一个简单的函数,该函数将交换任何两个相同类型的变量。
void swap(void* a, void* b, int size);
void swap(void* a, void* b, int size){
void* temp = malloc(size);
memcpy(temp, a,size);
memcpy(a, b, size);
memcpy(b, temp,size);
free(temp);
}
int main(int argc, char* argv[])
{
char name[] = "name";
char greet[] = "greet";
swap(name, greet, 30);
printf("%s\n", name);
printf("%s\n", greet);
return 0;
}
但是上面的代码显示的是:
`
name
memcpy(b,temp,size)之后,(交换)中指向的值更改为`,我不确定为什么吗?
答案 0 :(得分:0)
当您调用大小为30的memcpy(b, temp,size);
且b
所指向的字符串的实际大小为6时,您基本上会写遍您拥有的内存。
对于您而言,您的程序实际上会损坏程序堆栈。如果内存b
在a
之前,则额外的24个将有效地完全重写a
的内容。
您必须检查size
是否小于或等于两个字符串的最小大小+ 1(以解决空字符)。
答案 1 :(得分:0)
有一些错误,导致未定义的行为。 1.您正在从数组中复制30个字节,该数组长5个字节(“名称”是4个字符+ 1个尾随0字节)。 2.您正在将30个字节复制到数组中,该数组长6个字节(“ greet”是5个字符+ 1个字节的尾随0)。 这两个错误都可能引起问题,尤其是第二个错误:您试图在数组范围内使用24字节的内存-无法确定结果。
就像有人在评论中写道,更好的方法是交换指针,也不要指向字节。
答案 2 :(得分:0)
如评论所述,您不能交换greet
和name
,因为它们的类型不匹配:char[6]
与char[5]
(包括终止NUL),以及它们有不同的大小。
但是,swap
可以用于char *对象,因为char数组可以转换为char *,所以更改很简单。
int main(int argc, char* argv[])
char name[] = "name";
char greet[] = "greet";
char *p1 = name ;
char *p2 = greet ;
swap(&p1, &p2, sizeof(p1)) ;
printf("%s\n", p1);
printf("%s\n", p2);
}
侧面说明:除非您希望移动非常大的对象,否则无需在临时空间中使用malloc
。只需char temp[size] ;
即可完成工作-而不是malloc-无需释放(并获得较小的性能提升)。