8

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

然后我创建了两个“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 中的使用值,它也会改变 childB。

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

我知道这给了 childB 来自 childA 的所有值。我已经处理了 childB 中的其他字段,我只需要能够复制位于“child”结构中的名为 usage 的 rusage 结构。

4

7 回答 7

21

简单地:

childB.usage = childA.usage;
于 2009-09-24T23:04:27.587 回答
10

不应该是:

memcpy(&(childB.usage), &(childA.usage), sizeof(rusage))
于 2009-09-24T23:07:19.397 回答
3

编辑:好的,我误读了这个问题,您只想复制使用字段;所以我的回答有点无关紧要。我没有删除它,因为它仍然可以提醒初学者在分配或复制包含指针的结构时可能出现的别名问题。

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

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

或者

childA = childB;
if(childB.name)
  childA.name = strdup(childB.name);
于 2012-07-11T14:36:05.370 回答
0

childB.usage = childA.usage

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

于 2009-09-25T01:02:15.390 回答
0

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.

于 2009-09-29T10:51:59.730 回答
0

在这个文件中,我将 origine 的成员复制到 destinazione,首先仅使用 assignments 和 strcpy,然后,我将 origine 复制到 memres,仅使用 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;
}
于 2010-05-22T17:22:06.667 回答
0

首先,正确的代码是

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

其次,这将按原样复制值,因此对于所有这些 long 和 time 结构,它将是安全的,但是您拥有的 char* name 参数将指向相同的原始值。

于 2009-09-24T23:07:59.413 回答