Hello my task is to copy full structure into a new one, and allocate structure memory. I want to copy one structure into another and also I want to copy the memory of it. So if I "free" the first structure, then I will have this information in the memory located.
struct bmp_image* flip_vertically(const struct bmp_image* image) {
struct bmp_image* bmp = NULL;
bmp = (struct bmp_image*)realloc(bmp, sizeof(struct bmp_image));
memcpy(bmp, image, sizeof(struct bmp_image));
return bmp;
}
What can be the problem?
For example:
If I know that the
image->data[5].blue is 255 and I want to copy it but I need also to save that information into the memory
Main task is to flip the bmp picture. Everything is working perfect for me, but if I put this source code for test that writes that:
Running suite(s): flip_horizontally()
stderr
double free or corruption (!prev)
that means the test is somewhere free-ing the old structure so I don't have this information in the new one
struct bmp_header{
uint16_t type; // "BM" (0x42, 0x4D)
uint32_t size; // file size
uint16_t reserved1; // not used (0)
uint16_t reserved2; // not used (0)
uint32_t offset; // offset to image data (54B)
uint32_t dib_size; // DIB header size (40B)
uint32_t width; // width in pixels
uint32_t height; // height in pixels
uint16_t planes; // 1
uint16_t bpp; // bits per pixel (1/4/8/24)
uint32_t compression; // compression type (0/1/2) 0
uint32_t image_size; // size of picture in bytes, 0
uint32_t x_ppm; // X Pixels per meter (0)
uint32_t y_ppm; // X Pixels per meter (0)
uint32_t num_colors; // number of colors (0)
uint32_t important_colors; // important colors (0)
} __attribute__((__packed__));
/**
* This structure describes a color consisting of relative intensities of
* red, green, and blue.
*/
struct pixel {
uint8_t blue;
uint8_t green;
uint8_t red;
//uint8_t alpha;
} __attribute__((__packed__));
/**
* Structure describes the BMP file format, which consists from two parts:
* 1. the header (metadata)
* 2. the data (pixels)
*/
struct bmp_image {
struct bmp_header* header;
struct pixel* data; // nr. of pixels is `width` * `height`
};
Main.c
int main () {
struct bmp_image* image = NULL;
FILE *stream = fopen("assets/saboteur.bmp", "r");
image = read_bmp(stream);
FILE *output_p1 = fopen("square2.bmp", "w");
struct bmp_image* newimage1 = NULL;
newimage1 = flip_vertically(image);
free_bmp_image(image);
write_bmp(output_p1, newimage1);
free(newimage1);
fclose(output_p1);
fclose(stream);
return 0;
}
If I free the image (the old structure) it shows for me a lot of errors, and I can't write it to the file. That means for me that it wants to read from the old structure.
memcpy
does a "shallow" copy and not a "deep" copy. A shallow copy will copy only the pointer values in the struct bmp_image
and not the memory it points to. To do a deep copy, the individual fields need to be allocated and copied. Here is some illustrative code. Error checking has been left out for brevity but for final code all allocation results should be checked.
struct bmp_image* flip_vertically(const struct bmp_image* image) {
bmp = malloc(sizeof(*bmp));
bmp->header = malloc(sizeof(*(bmp->header)));
*bmp->header = *(image->header);
size_t pixel_data_size =
sizeof(*(bmp->data)) * bmp->header->width * bmp->header->height;
bmp->data = malloc(pixel_data_size);
memcpy(bmp->data, image->data, pixel_data_size);
return bmp;
}