C 编程。如何深度复制结构体?

发布于 2024-08-05 23:02:10 字数 1503 浏览 6 评论 0原文

我有以下两个结构,其中“子结构”有一个“rusage 结构”作为元素。

然后我创建两个“child”类型的结构体,我们称它们为 childA 和 childB

如何将 rusage 结构体从 childA 复制到 childB?

typedef struct{                         
        int numb;
        char *name;
        pid_t pid;
        long userT;
        long systemT;
        struct rusage usage;
}child;


typedef struct{
    struct timeval ru_utime; /* user time used */
    struct timeval ru_stime; /* system time used */
    long   ru_maxrss;        /* maximum resident set size */
    long   ru_ixrss;         /* integral shared memory size */
    long   ru_idrss;         /* integral unshared data size */
    long   ru_isrss;         /* integral unshared stack size */
    long   ru_minflt;        /* page reclaims */
    long   ru_majflt;        /* page faults */
    long   ru_nswap;         /* swaps */
    long   ru_inblock;       /* block input operations */
    long   ru_oublock;       /* block output operations */
    long   ru_msgsnd;        /* messages sent */
    long   ru_msgrcv;        /* messages received */
    long   ru_nsignals;      /* signals received */
    long   ru_nvcsw;         /* voluntary context switches */
    long   ru_nivcsw;        /* involuntary context switches */

}rusage;

我做了以下操作,但我猜它复制了内存位置,因为如果我更改了 childA 中的 use 值,它也会更改 childB 中的值。

memcpy(&childA,&childB, sizeof(rusage));

我知道这为 childB 提供了 childA 的所有值。我已经处理了 childB 中的其他字段,我只需要能够复制驻留在“child”结构中的名为“usage”的 rusage 结构。

I have the following two structs where "child struct" has a "rusage struct" as an element.

Then I create two structs of type "child" let's call them childA and childB

How do I copy just the rusage struct from childA to childB?

typedef struct{                         
        int numb;
        char *name;
        pid_t pid;
        long userT;
        long systemT;
        struct rusage usage;
}child;


typedef struct{
    struct timeval ru_utime; /* user time used */
    struct timeval ru_stime; /* system time used */
    long   ru_maxrss;        /* maximum resident set size */
    long   ru_ixrss;         /* integral shared memory size */
    long   ru_idrss;         /* integral unshared data size */
    long   ru_isrss;         /* integral unshared stack size */
    long   ru_minflt;        /* page reclaims */
    long   ru_majflt;        /* page faults */
    long   ru_nswap;         /* swaps */
    long   ru_inblock;       /* block input operations */
    long   ru_oublock;       /* block output operations */
    long   ru_msgsnd;        /* messages sent */
    long   ru_msgrcv;        /* messages received */
    long   ru_nsignals;      /* signals received */
    long   ru_nvcsw;         /* voluntary context switches */
    long   ru_nivcsw;        /* involuntary context switches */

}rusage;

I did the following, but I guess it copies the memory location, because if I changed the value of usage in childA, it also changes in childB.

memcpy(&childA,&childB, sizeof(rusage));

I know that gives childB all the values from childA. I have already taken care of the others fields in childB, I just need to be able to copy the rusage struct called usage that resides in the "child" struct.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

花开浅夏 2024-08-12 23:02:10

简单地:

childB.usage = childA.usage;

Simply:

childB.usage = childA.usage;
安静 2024-08-12 23:02:10

不应该是:

memcpy(&(childB.usage), &(childA.usage), sizeof(rusage))

Shouldn't it be:

memcpy(&(childB.usage), &(childA.usage), sizeof(rusage))
信仰 2024-08-12 23:02:10

编辑:好吧,我读错了问题,你只想复制用法字段;所以我的回答有点无关。我不删除它,因为它仍然可以提醒初学者在分配或复制包含指针的结构时潜在的别名问题。

memcpy 或其他答案的分配当然可以工作。 。结构中唯一的危险来自于指向名称的指针。如果将一个结构复制到另一个结构,您将拥有两个包含相同指针并指向相同内存的结构。您创建了一个别名。这意味着如果您更改分配的空间中的名称,它将从其他结构中可见。此外,如果将结构传递给标准自由函数,则存在双重free的危险。
要真正复制该结构,您应该执行类似的操作:

memcpy(&childA,&childB, sizeof(rusage));    
if(childB.name)
  childA.name = strdup(childB.name);

或者

childA = childB;
if(childB.name)
  childA.name = strdup(childB.name);

EDIT: Ok, I misread the question, you only wanted to copy the usage field; so my answer is a bit unrelated. I don't delete it because it can still remind beginners of the potential aliasing problem when assigning or duplicating a structure containing pointers.

The memcpy or assignement of the other answers will work, of course. The only danger in your structures comes from the pointer to name. If you copy one struct to the other you will have both structure containing the same pointer and pointing to the same memory. You created an alias. this means if yoy change the name in the allocated space, it will be visible from the other struct. Furthermore, there is the danger of a double free if you pass your structure to standard free function.
To make a real duplicate of the struct you should do something like that:

memcpy(&childA,&childB, sizeof(rusage));    
if(childB.name)
  childA.name = strdup(childB.name);

or alternatively

childA = childB;
if(childB.name)
  childA.name = strdup(childB.name);
北方的巷 2024-08-12 23:02:10

首先,正确的代码是

memcpy(&childA,&childB, sizeof(child));

第二,这将复制值,因此对于所有这些长和时间结构来说它都是安全的,
但您拥有的 char* name 参数将指向相同的原始值。

first, the correct code is

memcpy(&childA,&childB, sizeof(child));

second, this will copy the values asis, so for all those long and time structs it will be safe,
but the char* name parameter you have will pointer to the same original value.

红玫瑰 2024-08-12 23:02:10

childB.usage = childA.usage

由于您在子结构中拥有整个结构,因此简单的复制就足够了。如果您在子结构中有一个指向 rusage 结构的指针,那么这可能是一个问题。在这种情况下,您必须为 childB.usage 分配内存,然后执行 memcpy,这样如果有人修改/删除 childA,childB 将不会受到伤害。

childB.usage = childA.usage

Since you have the entire structure inside the child structure, simple copy suffices. If you had a pointer to rusage structure inside child structure, it could have been a problem. In that case, you would have had to allocate memory for childB.usage and then do a memcpy so that if anyone modifies/deletes childA, childB will be unharmed.

荆棘i 2024-08-12 23:02:10

正如其他人提到的,您可以通过两种方式来实现这一点。

1) childB.usage = childA.usage;
2) memcpy(&childB.usage, &childA.usage, sizeof(rusage));

memcpy 的第一个参数是目标,第二个参数是源,第三个参数是长度(要复制的字节数)。从您发布的代码来看,您试图将整个 childB 复制到 childA,这确实不是您想要的。

You could two that in two ways, as others have mentioned.

1) childB.usage = childA.usage;
2) memcpy(&childB.usage, &childA.usage, sizeof(rusage));

First argument of memcpy is the destination, second one is the source and the third one is length (how many bytes you want to copy). From the code you have posted, you were trying to copy the whole childB to childA, which is really not you wanted.

悲喜皆因你 2024-08-12 23:02:10

在此文件中,我将 origine 的成员复制到 destinazione,首先仅使用分配和 strcpy,然后,我仅使用 memcpy 将 origine 复制到 memres

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

typedef struct inner
{
    char *parola;
    int n;
} interna;

typedef struct outer
{
    struct inner *ptr;
    int numeroesterno;
} esterna;


struct another
{
    struct inner *ptr;
    int numero;
};    //never forget ; here

int main(void)
{
    esterna *origine; //ptr to structs
    struct another *destinazione;
    struct another *memres;

    char *tmpParola;
    tmpParola = malloc(30*sizeof(char));
    strcpy(tmpParola, "AAAAA");

    interna *tmp;  //remember the TYPEDEF, and don't use struct interna
    tmp = (interna *)malloc(sizeof(struct inner));
    // if you use struct interna in sizeof you get
    //  error: invalid application of ‘sizeof’ to incomplete type ‘struct interna’ 

    tmp->n = 500;
    tmp->parola = tmpParola;

    origine = (esterna *)malloc(sizeof(struct outer));

    origine->numeroesterno = 2;
    origine->ptr = tmp;  //the data structer pointed by tmp has already been allocated and set

    // now I have the structure allocated and set, I want to copy this on destinazione
    destinazione = (struct another *)malloc(sizeof(struct another));

    destinazione->numero = origine->numeroesterno;

    //destinazione->ptr = tmp;  //in this case you don't copy struct inner, it's just a reference

    destinazione->ptr = (interna *)malloc(sizeof(struct inner));
    destinazione->ptr->parola = malloc(sizeof(char)*30);
    strcpy(destinazione->ptr->parola, origine->ptr->parola);
    destinazione->ptr->n = 111;

    //modify origine

    origine->numeroesterno = 9999;
    strcpy(origine->ptr->parola, "parola modificata in origine");

    //print destinazione

    printf("\nparola in destinazione :%s\n", destinazione->ptr->parola);
    printf("\nparola in origine :%s\n", origine->ptr->parola);

    //you can see that destinazione is a copy, because mofifying origine, destinazione deosn't change

    //now we play with memcpy

    memres = (struct another *)malloc(sizeof(struct another));

    memcpy(memres, destinazione, sizeof(destinazione)); //till here, is AAAAA
    strcpy(destinazione->ptr->parola, "parola modificata in destinazione");

    printf("\nmemcpy, numero %d\n", memres->numero);
    printf("\nmemcpy, parola :%s\n", memres->ptr->parola);

    //as you can see from the output, memcpy doesn't make a copy of destinazione:
    //modifying destinazione->ptr->parola after the assignment affects what memres carries with it
    //So from the idea that I got, memcpy just creates the pointers to the originary structure

    free(origine->ptr->parola);
    free(origine->ptr);
    return 0;
}

in this file I copy the members of origine to destinazione, first only using assignments and strcpy, then, i copy origine to memres, using only memcpy

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

typedef struct inner
{
    char *parola;
    int n;
} interna;

typedef struct outer
{
    struct inner *ptr;
    int numeroesterno;
} esterna;


struct another
{
    struct inner *ptr;
    int numero;
};    //never forget ; here

int main(void)
{
    esterna *origine; //ptr to structs
    struct another *destinazione;
    struct another *memres;

    char *tmpParola;
    tmpParola = malloc(30*sizeof(char));
    strcpy(tmpParola, "AAAAA");

    interna *tmp;  //remember the TYPEDEF, and don't use struct interna
    tmp = (interna *)malloc(sizeof(struct inner));
    // if you use struct interna in sizeof you get
    //  error: invalid application of ‘sizeof’ to incomplete type ‘struct interna’ 

    tmp->n = 500;
    tmp->parola = tmpParola;

    origine = (esterna *)malloc(sizeof(struct outer));

    origine->numeroesterno = 2;
    origine->ptr = tmp;  //the data structer pointed by tmp has already been allocated and set

    // now I have the structure allocated and set, I want to copy this on destinazione
    destinazione = (struct another *)malloc(sizeof(struct another));

    destinazione->numero = origine->numeroesterno;

    //destinazione->ptr = tmp;  //in this case you don't copy struct inner, it's just a reference

    destinazione->ptr = (interna *)malloc(sizeof(struct inner));
    destinazione->ptr->parola = malloc(sizeof(char)*30);
    strcpy(destinazione->ptr->parola, origine->ptr->parola);
    destinazione->ptr->n = 111;

    //modify origine

    origine->numeroesterno = 9999;
    strcpy(origine->ptr->parola, "parola modificata in origine");

    //print destinazione

    printf("\nparola in destinazione :%s\n", destinazione->ptr->parola);
    printf("\nparola in origine :%s\n", origine->ptr->parola);

    //you can see that destinazione is a copy, because mofifying origine, destinazione deosn't change

    //now we play with memcpy

    memres = (struct another *)malloc(sizeof(struct another));

    memcpy(memres, destinazione, sizeof(destinazione)); //till here, is AAAAA
    strcpy(destinazione->ptr->parola, "parola modificata in destinazione");

    printf("\nmemcpy, numero %d\n", memres->numero);
    printf("\nmemcpy, parola :%s\n", memres->ptr->parola);

    //as you can see from the output, memcpy doesn't make a copy of destinazione:
    //modifying destinazione->ptr->parola after the assignment affects what memres carries with it
    //So from the idea that I got, memcpy just creates the pointers to the originary structure

    free(origine->ptr->parola);
    free(origine->ptr);
    return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文