'Trying to deep copy a structure in C, but I keep failing, any ideas?

So basically I'm trying to flip an Image structure I've made in C, however I keep mirroring it right down the middle. This clearly means that I'm overwriting the image as I'm flipping it, so my copy isn't working. Any ideas on how I should be doing this??

Here's the code where I define my structure:

struct Image {
    int width, height;  // Width (=no. columns) and height (=no. rows) of the image.
    int **pixels;       // pixels[row][col] for each one
};

And this is the code where I attempt to flip it:

void flipImage(struct Image *img)
{
    struct Image *imgCopy = (struct Image *)malloc(sizeof(struct Image));
    memcpy(imgCopy, img, sizeof(struct Image));
    printf("done with copy");

    int row, col;
    for (row = 0; row < img->height; row++)
        for (col = 0; col < img->width; col++)
            imgCopy->pixels[row][col] = img->pixels[row][img->width - col - 1];

    outputFlippedImage(imgCopy);
}

I thought that memcpy was used to essentially deep copy things, but this doesn't seem to be the case. Kind of lost as to what to attempt next. I've sat here for the past hours scratching my head :///

UPDATE:

I've tried to get the deep copy working, up still have had no luck :( This is what I'm trying now, still yielding the wrong results. To clarify I'm trying to flip an image like so:

123 -> 321

As in flipping it from left to right. Here's my latest attempt:

void flipImage(struct Image *img)
{
    struct Image *imgCopy = malloc(sizeof(struct Image));
    *imgCopy = *img;

    memcpy(&imgCopy->height, &img->height, sizeof(img->height));
    memcpy(&imgCopy->width, &img->width, sizeof(img->width));
    memcpy(&imgCopy->pixels, &img->pixels, sizeof(img->pixels));
    printf("done with copy");

    int row, col;
    for (row = 0; row < img->height; row++)
        for (col = 0; col < img->width; col++)
            imgCopy->pixels[row][col] = img->pixels[row][img->width - col - 1];

    outputFlippedImage(imgCopy);
}
c


Solution 1:[1]

You do not allocate a copy of the pixel array, nor do you allocate copies of the individual scanlines pointed to by the pixel array. Your copy and the original structure share the same data so the modification you perform on the copy is actually performed on the source image too.

Here is a modified version:

struct Image {
    int width, height;  // Width (=no. columns) and height (=no. rows) of the image.
    int **pixels;       // pixels[row][col] for each one
};

void flipImage(const struct Image *img)
{
    struct Image *imgCopy = malloc(sizeof(*imgCopy));
    imgCopy->width = img->width;
    imgCopy->height = img->height;
    imgCopy->pixels = calloc(img->rows, sizeof(*imgCopy->pixels));
    for (int row = 0; row < img->rows; row++) {
        imgCopy->pixels[row] = malloc(img->cols * sizeof(*imgCopy->pixels[i]));
        for (col = 0; col < img->width; col++)
            imgCopy->pixels[row][col] = img->pixels[row][img->width - col - 1];
        }
    }
    outputFlippedImage(imgCopy);

    // free copy.
    for (int row = 0; row < img->rows; row++) {
        free(imgCopy->pixels[row]);
    }
    free(imgCopy->pixels);
    free(imgCopy);
}

I would recommend using separate functions to clone, flip and free image structures.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1