1

I would like to copy a structure from an another structure like this:

#include <stdio.h>
#include <stdlib.h>


struct foo_struct{
    int foo;
    char *str;
};

static void foo(struct foo_struct *, struct foo_struct *);
void main(void) {
    int i;
    struct foo_struct *test = malloc(sizeof(struct foo_struct) * 5);
    struct foo_struct *cpy_struct = NULL;

    foo(test, cpy_struct);

    cpy_struct->foo = 20;
    //printf("%d\n", cpy_struct.foo);

    free(test);
}

static void foo(struct foo_struct *test, struct foo_struct *cpy){
    int i;
    for(i = 0; i < 5; i++)
        test[i].foo = i;    

    cpy = &test[2];
}

But, when I modify this entry: cpy_struct->foo = 20;, I had a segmentation fault.

When I didn't use the pointer in struct foo_struct cpy_struct, I modify my entry, but not a original structure:

struct foo_struct cpy_struct = {0};

foo(test, &cpy_struct);

cpy_struct.foo = 20;
printf("%d\n", cpy_struct.foo); /* Display 20 */
printf("%d\n", test[2].foo);    /* Display 2 */

/* ... */

static void foo(struct foo_struct *test, struct foo_struct *cpy){
    int i;
    for(i = 0; i < 5; i++)
        test[i].foo = i;

    *cpy = test[2];
}

How can I copy this struct to update the value in specific structure ?

Thank you.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
gbucchino
  • 21
  • 3
  • 3
    You need to pass the address of `cpy_struct` to `foo()` and update `cpy` in that function like `*cpy = &test[2]`. In your case the value in `cpy` updated in the function is lost when `foo()` returns – kuro Dec 04 '19 at 08:00

4 Answers4

1

For the 2nd case, you need to fix the order of assignment. Current code copies test[2] to cpy_struct, and then modifies it to 20. The output will be 20. Consider the following

struct foo_struct cpy_struct = {0};

cpy_struct.foo = 20;

foo(test, &cpy_struct);

printf("%d\n", cpy_struct.foo); /* Display 2 */
printf("%d\n", test[2].foo);    /* Display 2 */
dash-o
  • 13,723
  • 1
  • 10
  • 37
  • Thank you, but, when I would like the cpy_struct entry, I would like to modify `test[2].foo`, and in the 2nd case, isn't possible. – gbucchino Dec 04 '19 at 08:20
0

For your first case

#include <stdio.h>
#include <stdlib.h>


struct foo_struct{
    int foo;
    char *str;
};

static void foo(struct foo_struct *, struct foo_struct **);
void main(void) {
    int i;
    struct foo_struct *test = malloc(sizeof(struct foo_struct) * 5);
    struct foo_struct *cpy_struct = NULL;

    foo(test, &cpy_struct);

    //cpy_struct->foo = 20;
    printf("%d\n", cpy_struct->foo);

    free(test);
}

static void foo(struct foo_struct *test, struct foo_struct **cpy){
    int i;
    for(i = 0; i < 5; i++)
        test[i].foo = i;    

    *cpy = &test[2];
}

What you did is you assign the address of test[2] as the value of cpy_struct. What you need to do is to assign the address of test[2] to the address of cpy_struct.

To do this, you have to make the argument of foo as pointer to pointer so that the when you assign something to *cpy, it assign to the address of cpy_struct, not its value.

I've corrected the code, and tested it. The printf result is 2 since I comment out the assignment of cpy_struct->foo = 20;

0

Thank you, I never used pointer to pointer... I'm trying and it's work with this code:

static void foo(struct foo_struct *, struct foo_struct **);
void main(void) {
    int i;
    struct foo_struct *test = malloc(sizeof(struct foo_struct) * 5);
    struct foo_struct *cpy_struct = NULL;

    foo(test, &cpy_struct);

    cpy_struct->foo = 20;
    printf("%d\n", cpy_struct->foo); /* Display 20 */
    printf("%d\n", test[2].foo);     /* Display 20 */

    free(test);
}

static void foo(struct foo_struct *test, struct foo_struct **cpy){
    int i;
    for(i = 0; i < 5; i++)
        test[i].foo = i;    

    *cpy = &test[2];
}
gbucchino
  • 21
  • 3
-1

In the first program you have to pass the pointer by reference.

For example

static void foo(struct foo_struct *test, struct foo_struct **cpy){
    int i;
    for(i = 0; i < 5; i++)
        test[i].foo = i;    

    *cpy = test + 2;
}

and call the function like

foo(test, &cpy_struct);

In this case the pointer cpy_struct in main will point to the third element of the array pointed to by test.

In the second program you created a new object of the structure type and copied into it the object pointed to by test + 2. So as a result you have a separate object.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335