通用类型交换C函数

时间:2019-12-01 19:22:46

标签: 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(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)之后,(交换)中指向的值更改为`,我不确定为什么吗?

3 个答案:

答案 0 :(得分:0)

当您调用大小为30的memcpy(b, temp,size);b所指向的字符串的实际大小为6时,您基本上会写遍您拥有的内存。

对于您而言,您的程序实际上会损坏程序堆栈。如果内存ba之前,则额外的24个将有效地完全重写a的内容。

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

答案 1 :(得分:0)

有一些错误,导致未定义的行为。 1.您正在从数组中复制30个字节,该数组长5个字节(“名称”是4个字符+ 1个尾随0字节)。 2.您正在将30个字节复制到数组中,该数组长6个字节(“ greet”是5个字符+ 1个字节的尾随0)。 这两个错误都可能引起问题,尤其是第二个错误:您试图在数组范围内使用24字节的内存-无法确定结果。

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

答案 2 :(得分:0)

如评论所述,您不能交换greetname,因为它们的类型不匹配: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-无需释放(并获得较小的性能提升)。