Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I have an array of complex numbers, and I just want to swap between two elements. However, I want to implement the swap for unknown types (using void*). So I wrote the following code, using the first swap implementation that I saw here:

#include<stdio.h>

typedef struct complex complex;

struct complex {
    int real;
    int img;
};

void swap(void *arr[], int i, int j)
{
    void *temp;
    temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

void printComplexArray(complex* cArr, size_t len)
{
    int i;
    for (i = 0; i < len; i++)
    {
        printf("Cell %d : real- %d , img- %d
", i, cArr[i].real, cArr[i].img);
    }
}

void main(void)
{
    complex cArr[] = { { 22, 3 },{ 1, 13 },{ 5, 7 },{ 8, 4 } };
    size_t cLen = (sizeof(cArr) / sizeof(cArr[0]));
    swap(cArr, 1, 2);
    printComplexArray(cArr, cLen);
}

I expected to get:

Cell 0 : real- 22 , img- 3
Cell 1 : real- 5 , img- 7
Cell 2 : real- 1 , img- 13
Cell 3 : real- 8 , img- 4

But I got:

Cell 0 : real- 22 , img- 1
Cell 1 : real- 3 , img- 13
Cell 2 : real- 5 , img- 7
Cell 3 : real- 8 , img- 4                     

As you can see, not only that the swapping wasn't performed correctly- the content of some array elements was changed. Can you explain why, and how can I fix this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
283 views
Welcome To Ask or Share your Answers For Others

1 Answer

You probably want this:

void swap(struct complex arr[], int i, int j)
{
    struct complex temp;
    temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

Your solution swaps pointers but your array doesn't contain pointers but struct complexs. That's basically what the compiler warning told you.

If you really want to swap unknown types, you need this:

void swap(void *arr, int i, int j, size_t size)
{
    char temp[size];
    char *a = (char*)arr;

    memcpy(temp, (a + size * i), size);
    memcpy((a + size * i), (a + size * j), size);
    memcpy((a + size * j), temp, size);
}
...
swap(cArr, 1, 2, sizeof(*cArr));

The size parameter is necessary because if the type is unknown, the size of the type is of course unknown too and therefore you need to specify the size.

For memcpy you need to include <memory.h>, so you must write your own memcpy, as you are allowed to include only <stdio.h>.

Some compilers won't allow char temp[size]; so you just can use char temp[MAX_SIZE]; with MAX_SIZE defined to the maximum expected size for your unknown types.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...