-2

I am trying to make a generic swap function using memcpy() in C. I am getting a garbage value when I try to swap arrays.

This is code below:

#include<stdio.h>
#include<string.h>

typedef struct Student
{
    char a[10];
    int b;
    double c;
}   Student;

void swap(void* one, void* two,size_t size)

{
    char temp[size] ;
    memcpy(temp,two,size); // temp = *two;
    memcpy(two,one,size);//*two = *one;
    memcpy(one,temp,size);//*one = temp;
}

int main()
{
    int i1 = 10, i2 = 20;
    float f1 = 1.6, f2 = 8.9;
    int a1[3] = {1, 2, 3}, a2[3] = {10, 20, 30};
    Student s1 = {"Mark", 42, 5.2}, s2 = {"Bilal", 9, 3};
    swap(&i1,&i2,sizeof(int));
    printf(" i1 = %d \n i2 = %d\n",i1,i2);
    swap(&f1,&f2,sizeof(double));
    printf(" f1 = %f \n f2 = %f\n",f1,f2);
    swap(&a1,&a2,sizeof(a2));
    printf(" a1 = %d %d %d  \n a2 = %d %d %d ",a1[0],a1[1],a1[2],a2[0],a2[1],a2[2]);

}

The output is below:

Enter image description here

I am also getting a garbage value for the array.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131

4 Answers4

5

The problem is very likely

swap(&f1,&f2,sizeof(double));

The variables f1 and f2 are of type float, not double. The size of float is commonly four bytes, while the size of double is eight bytes.

Because you pass the wrong size your memcpy calls will go out of bounds and lead to undefined behavior.

Use the size of the variables instead:

swap(&f1,&f2,sizeof f1);

NB: That the value of f2 is printed as zero should be a pretty big hint that the problem lies there.


Also note that &a1 and &a2 is wrong. Those are pointers to the actual arrays themselves, while you should pass pointers to the first element of the array. The type of both &a1 and &a2 is int (*)[3], but you should pass int *. Instead pass e.g. &a1[0], or just plain a1 as that will decay to a pointer to its first element.

Harith
  • 4,663
  • 1
  • 5
  • 20
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
2

Floats are 4 bytes, while doubles are 8 bytes. The code got confused and overwrote memory (a hazard of memcpy()).

See below:

int main( void )
{
    int i1 = 10, i2 = 20; // Integers
    swap( &i1, &i2, sizeof i1 );
    printf(" i1 = %d \n i2 = %d\n",i1,i2);

    float f1 = 1.6, f2 = 8.9; // Floats
    swap( &f1, &f2, sizeof f1 ); // NOT sizeof "double"!!
    printf(" f1 = %f \n f2 = %f\n",f1,f2);

    int a1[3] = {1, 2, 3}, a2[3] = {10, 20, 30}; // arrays
    swap( a1, a2, sizeof a1 );
    printf(" a1 = %d %d %d  \n a2 = %d %d %d ",a1[0],a1[1],a1[2],a2[0],a2[1],a2[2]);

    Student s1 = {"Mark", 42, 5.2}, s2 = {"Bilal", 9, 3};
    // and so on...
}

Ask yourself why you entangled all the definitions without printing each as it appeared in the code.

Further, by using the sizeof() the destination variable, you are less likely to overrun the destination buffer, even if the source is incorrect.

Fe2O3
  • 6,077
  • 2
  • 4
  • 20
0
swap(&f1,&f2,sizeof(double));

It is one of the classic examples why one should not use types in sizeof.

swap(&f1,&f2,sizeof(f1));

solves the problem for any f1 type.

0___________
  • 60,014
  • 4
  • 34
  • 74
-4

Please try this

#include <stdio.h>
#include <string.h>

typedef struct Student {
char a[10];
int b;
double c;
} Student;

void swap(void* one, void* two, size_t size) {
char temp[size];
memcpy(temp, one, size);
memcpy(one, two, size);
memcpy(two, temp, size);
}

int main() {
int i1 = 10, i2 = 20;
float f1 = 1.6, f2 = 8.9;
int a1[3] = {1, 2, 3}, a2[3] = {10, 20, 30};
Student s1 = {"Mark", 42, 5.2}, s2 = {"Bilal", 9, 3};

swap(&i1, &i2, sizeof(int));
printf("i1 = %d\ni2 = %d\n", i1, i2);

swap(&f1, &f2, sizeof(float));
printf("f1 = %f\nf2 = %f\n", f1, f2);

for (int i = 0; i < 3; i++)
    swap(&a1[i], &a2[i], sizeof(int));

printf("a1 = %d %d %d\na2 = %d %d %d\n", a1[0], a1[1], a1[2], 
a2[0], 
a2[1], a2[2]);

return 0;
}

Explanation:

The swap function remains the same. We are still using memcpy to swap the memory of two variables, but now it's properly aligned with their respective data types.

The issue with the float values is fixed by passing the correct size of float (use sizeof(float)) to the swap function.

The array swap inside the loop is also fixed by passing the correct size of int (use sizeof(int)) to the swap function.

After making these corrections, the code should work as expected without any garbage value issues.

  • 1
    Welcome to SO. Your attempt to help is appreciated. Nevertheless, code-only answers without any explanation are considered low quality. Also, that loop you introduce defeats the purpose of the example to swap data objects of any size. Finally, you should apply some decent formatting to your code. With close to no indentation at all, the formatting is rather poor. – Gerhardh Jul 25 '23 at 07:09
  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 28 '23 at 14:05
  • 1
    A belated Welcome to the site! I see this was your first answer. The community correctly pointed out that *explanations* are better than (or in addition to) code-only answers. However, your explanation (and now that I look closely at it, perhaps your code as well) appears to have been generated by an AI such as ChatGPT (or VSCode Copilot), and while I'm not an expert in C, it doesn't quite "fit", especially when compared to the other answers here. If you used an AI, a heads-up that [that's not allowed here](//meta.stackoverflow.com/q/421831). – NotTheDr01ds Aug 11 '23 at 16:24
  • 1
    We do hope you'll stick around and continue to be a valuable part of our community by posting your own quality content. Thanks! – NotTheDr01ds Aug 11 '23 at 16:24
  • Missing indentation of code is usually a sign it has been copied off a web page somewhere (the indentation is not missing in the question)—a web page that doesn't support the multiple (leading) spaces in the code, like raw HTML. How was the indentation lost? Using [Bing Chat](https://en.wikipedia.org/wiki/Microsoft_Bing#AI_integration_(2023%E2%80%93))? – Peter Mortensen Aug 15 '23 at 11:29
  • The code was also reformatted. Did you do it yourself, or did an AI assistant (or some other tool) do it? – Peter Mortensen Aug 15 '23 at 11:34
  • Re *"The array swap inside the loop is also fixed"*: But there isn't a *for* loop in the original code. What is the explanation? – Peter Mortensen Aug 15 '23 at 11:37
  • I have rewrited the code on my behalf to fix that issue. Thanks – Sahil Rana Aug 24 '23 at 18:26
  • I have posted for the first time. I don't actually knows how to put the code there. So I tried my level best, that's wh there are lack of indentation – Sahil Rana Aug 24 '23 at 18:27