泛型交换c函数

泛型交换c函数,c,debugging,heap,C,Debugging,Heap,我正在尝试编写一个简单的函数,它将交换相同类型的任意两个变量 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(i

我正在尝试编写一个简单的函数,它将交换相同类型的任意两个变量

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
a(在交换中)指向的值在memcpy(b,temp,size)之后变为`我不确定为什么?

当您调用
memcpy(b,temp,size)时
当size等于30,而
b
所指字符串的实际大小为6时,您基本上可以通过自己拥有的内存进行写操作

在您的情况下,您的程序实际上会损坏程序堆栈。如果内存中
b
位于
a
之前,则额外的24个将有效地完全重写
a
的内容


您必须检查
大小
是否小于或等于两个字符串的最小大小+1(以说明空字符)。

存在一些错误,导致未定义的行为。 1.您正在从一个5字节长的数组中复制30个字节(“name”是4个字符+1个尾随0的字节)。 2.您正在将30个字节复制到数组中,该数组的长度为6字节(“greet”是5个字符+1个字节的尾随0)。 这两个bug都可能导致问题,特别是第二个bug:您正试图在数组边界上使用24字节的内存,因此无法确定结果


有人在评论中写道,更好的方法是交换指针,也不是指针字节。

如评论所述,您不能交换
greet
name
,因为它们的类型不匹配:
char[6]
,vs
char[5]
(包括终止NUL),并且它们的大小不同

但是,可以在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
,除非您希望移动非常大的对象。只是<代码>字符温度[大小]将完成这项工作,而不是malloc,并且不需要免费(性能也会有轻微的提高)。

您不能交换
name
greet
,因为它们的大小不同。当然,你不能用30号来交换它们,因为这比任何一个都大!越界总是会导致未定义的行为。我在两个大小相同的字符串上测试了您的代码(将该大小作为第三个参数传递给
swap
),结果成功了。因此,您的
swap
函数看起来不错。在重新排列字符串时,使用指针并重新排列它们通常比复制整个字符串更容易、更有效。我应该如何更改函数以具有相同的定义并处理所有类型(字符串、字符、浮点、双精度、整数等)?swap不仅仅用于字符串,它将与int、float等一起工作,因此我不能将temp设置为char数组。我应该如何更改我的函数,使其具有相同的定义并与所有类型(string、char、float、double、int等)一起工作?@MohamedMoustafa我不明白为什么需要对“swap”进行任何更改,只要这两个参数具有相同的类型。哪种can/类型不起作用?我应该如何更改我的函数,使其具有相同的定义并适用于所有类型(string、char、float、double、int等)?您的函数已经适用于所有类型。只是知道参数的大小不是函数的工作,而是将要使用函数的程序员的工作。这是C语言中的一个普遍主题,函数完全信任程序员。例如
memcpy
函数:它完全依赖于您检查您写入的数据量是否不超过您实际可以写入目标的数据量这一事实。相反,
scanf
返回它解析的参数数量,因为程序员甚至在理论上也不知道输入是否正确。我应该如何更改我的函数,使其具有相同的定义,并使用所有类型(字符串、字符、浮点、双精度、int等)?