-2

I want to use C to copy all content i from struct member indexs to struct A with memcpy. I don't know how to do that. Can you please show me how it done if even possible?

Let say we have 3 defined struct's:

struct A {
    int destination[100];
};

struct B
{
  int i;
};


struct C {
    struct B ** indexs;
};

The idea is to get from struct C all member indexs and copy from indexs all the content of i to struct A:

struct A  a;

struct C * tasks = calloc(2,  sizeof(struct C));

tasks[0].indexs = (struct B **)calloc((size_t)5, sizeof(struct B *));
tasks[0].indexs[0] = malloc(sizeof (int));
tasks[0].indexs[1] = malloc(sizeof (int));
tasks[0].indexs[2] = malloc(sizeof (int));
tasks[0].indexs[3] = malloc(sizeof (int));

tasks[0].indexs[0]->i =1;
tasks[0].indexs[1]->i =2;
tasks[0].indexs[2]->i =3;
tasks[0].indexs[3]->i =4;

memcpy(&a.destination, &tasks[0].indexs[0]->i, 100 * sizeof (int));

printf("Hello World: %i ", a.destination[1]);
  • 1
    First, try to compile the code yourself and remove the compiler errors. – Olaf Dietsche Feb 28 '23 at 13:02
  • After removing the compile error, look at `calloc(struct B)`: you allocate an array of `struct B`s, but assign it to an array of *pointers to struct B*. – Olaf Dietsche Feb 28 '23 at 13:07
  • 1
    The expression `calloc(100, sizeof(struct B))` will allocate memory for `100` elements of type `struct B`. It returns a pointer to the first element. That pointer will have the type `struct B *`. It's a dynamic allocation of an array of `B` structures, similar to `struct B array[100];`. Why do you then use `struct B **` for the returned pointer? That would only make sense if you created an array of *pointers* to `struct B` (like `struct B *array[100];`). Or a dynamic "2D" jagged array of `struct B` objects. – Some programmer dude Feb 28 '23 at 13:09
  • 2
    You may want to visualize the memory layout. Draw a picture of (array of) structs and how they are connected via pointer arrows. – Olaf Dietsche Feb 28 '23 at 13:10
  • 1
    The potential for [trailing padding](https://stackoverflow.com/q/119123/2505965) in `struct B` makes this a dubious approach, even if the alignment of each structure happens to work out in this particular example (i.e., `sizeof (struct B) == sizeof (int)`). Best to write your own copying function(s) (after fixing the type issues). – Oka Feb 28 '23 at 13:12
  • I have removed all compile error... but still no luck with memcpy.. it print 0 instead of 2 – dsfddg dggd Feb 28 '23 at 14:02
  • indexs => indexes – i486 Feb 28 '23 at 14:08
  • @i486 this don't solve anything it just naming – dsfddg dggd Feb 28 '23 at 14:09
  • `tasks[0].indexs[0] = malloc(sizeof (int));`? But `tasks[i].indexs[j]` is supposed to be a `B` object, not an `int`. There's no guarantee that the size of `B` is equal to the size of `int` (see [Why isn't sizeof for a struct equal to the sum of sizeof of each member?](https://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member)). – Some programmer dude Feb 28 '23 at 14:31
  • Also, why do you need an array of *pointers*? What is the problem that is supposed to solve? Why can't you have an array of `B` structure objects? Like `struct B *indexs;` – Some programmer dude Feb 28 '23 at 14:31
  • @dsfddgdggd It is a comment, not answer. – i486 Feb 28 '23 at 14:38

1 Answers1

0

The call to memcpy

memcpy(&a.destination, &tasks[0].indexs[0]->i, 100 * sizeof (int));

is just plain wrong.

&tasks[0].indexs[0]->i is a pointer to a single int value, it's not an array, it's not a pointer, it's a single plain int value.

Because &tasks[0].indexs[0]->i is a pointer to a single int value, and not the first element of an array, the memcpy call will go well out of bounds of that single value. And going out of bounds leads to undefined behavior.

You can't copy a set of single distinct values into an array using memcpy, you need to use an explicit loop to copy them one by one:

for (size_t i = 0; i < 100; ++i)
{
    a.destination[i] = tasks[0].indexs[i]->i;
}

Also note that the memcpy call is wrong for another reason as well: &a.destination is a pointer to the array itself, with a type of int (*)[100].

What is expected is a pointer to the first element of the array which would be &a.destination[0] (or just plain a.destination which will decay to the correct pointer type).

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 1
    i'm using double pointers, becouse NULL can be used only with pointers and struct B *indexs; will result in copy of other pointer - thank you for the solution that is also the only way i could think of – dsfddg dggd Feb 28 '23 at 18:08