1

If I have a structure defined like:

struct image{
unsigned int width, height;
unsigned char *data;
};

And 2 variables of this type:

struct image image1;
struct image image2;

I want to transfer the data from image1 to the data of image2(presuming image1 has some data written, and image2 has data allocated with malloc or calloc). How can it be done? Thanks a lot.

biggdman
  • 2,028
  • 7
  • 32
  • 37

5 Answers5

5

Assuming it is undesirable that two instances of struct image are pointing to the same data then memcpy() cannot be used to copy the structs. To copy:

  • allocate memory for destination struct
  • allocate memory for destination data buffer based on source data
  • assign width members
  • memcpy() data members.

For example:

struct image* deep_copy_image(const struct image* img)
{
    struct image* result = malloc(sizeof(*result));
    if (result)
    {
        /* Assuming 'width' means "number of elements" in 'data'. */
        result->width = img->width;
        result->data = malloc(img->width);
        if (result->data)
        {
            memcpy(result->data, img->data, result->width);
        }
        else
        {
            free(result);
            result = NULL;
        }
    }
    return result;
}
hmjd
  • 120,187
  • 20
  • 207
  • 252
2

did you try memcpy(&image1,&image2,sizeof(image));

edit: Alocate data for image2.data after that you have to strcpy(image2.data,image1.data) if data is null terminated, but if its not, then use memcpy with the size of data.

Regards, Luka

Luka Pivk
  • 466
  • 2
  • 19
2
struct image image1;
struct image image2;

...

image2.width = image1.width;
image2.height = image1.height;

/* assuming data size is width*height bytes, and image2.data has enough space allocated: */

memcpy(image2.data, image1.data, width*height);
Jomu
  • 349
  • 2
  • 5
1

It's simple in C. Simply do the following (assuming image2 is uninitialized):

image2 = image1;  //there's no deep copy, pointed to memory isn't copied

You can assign one structure variable to other given they are of the same type. No need to copy piece-meal. This is a useful feature of C.

This has been discussed before:

Assign one struct to another in C

Oriol Roma
  • 329
  • 1
  • 5
  • 9
Rüppell's Vulture
  • 3,583
  • 7
  • 35
  • 49
  • -1. Sorry, but this leaks any existing `data` member of `image2`. If you assume that `image2` is effectively uninitialised before this assignment, it'll be important to say this explicitly. – simonc May 03 '13 at 14:11
  • @simonc You contradict the link above, and the answer with 26 upvotes. – Rüppell's Vulture May 03 '13 at 14:13
  • I don't think I contradict that question - this is just a slightly more complex situation. The [most popular answer](http://stackoverflow.com/a/2302357/311966) to that question hints at the problems you'll run into when your structs own dynamically allocated memory. – simonc May 03 '13 at 14:18
  • @simonc Before we wrap up,please give me a short but rigorous difference between shallow copy and deep copy.I think I am fuzzy about that. – Rüppell's Vulture May 03 '13 at 14:19
  • Shallow copy - copy struct members, including addresses of pointer members. Deep copy - copy by-value members, allocate copies of pointer members that own memory, copy addresses of pointer members that don't own memory. Does that make sense? – simonc May 03 '13 at 14:22
  • @simonc Plz elaborate more on `allocate copies of pointer members that own memory, copy addresses of pointer members that don't own memory`. – Rüppell's Vulture May 03 '13 at 14:26
  • @simonc Please elaborate on that part of your comment. – Rüppell's Vulture May 03 '13 at 14:37
  • For the struct in this question, a shallow copy of `data` would just involve `image2.data = image1.data;`. If `image2.data` had previously pointed to malloced data, this would be leaked. A deep copy might involve something like `free(image2.data); image2.data = malloc(image1.width * image1.height); memcpy(image2.data, image1.data, image1.width * image1.height);` – simonc May 03 '13 at 14:43
  • @simonc Thank you read-coat!!Else I would have had to read a lot of pages to make sense of that.Red-coat or kilt? – Rüppell's Vulture May 03 '13 at 14:46
1

If all you want is duplicating the struct (i. e. creating a "shallow" copy):

image2 = image1;

if you also want to copy the data pointed to by image1.data ("deep copy"), then you need to do that manually:

memcpy(image2.data, image1.data, image1.width * image1.height);

(assuming there are image1.width * image1.height bytes in the data, and there's enough space malloc()ated in image2.data for storing that.)

  • With this `image2.data` will point to `image1.data` which is not correct. Each member should be copied separately. – Rohan May 03 '13 at 14:13
  • @H2CO3 The shallow copy section might benefit from a mention that any allocated `data` member of `image2` would be leaked. – simonc May 03 '13 at 14:14
  • @Rohan Huh what? "With this" - with what? –  May 03 '13 at 15:45