将struct的动态数组复制到另一个struct

时间:2022-09-06 11:23:07

I have a struct defined like this:

我有这样一个结构体

struct Queries {

    uint64_t Id;
    uint64_t from;  
    uint32_t counter; // total queries
    char queries[];
};

What I am trying to do is create a new struct "object" and copy the values from an existing one to this new object.

我要做的是创建一个新的struct“对象”并将现有的值复制到这个新对象。

What I tried

我试着什么

void function(Queries* oldq){

    Queries* q = new Queries();

    // values are copied correctly
    q->Id = oldq->Id;
    q->from = oldq->from;
    q->counter = oldq->counter;

    // copy is not correct
    for (unsinged i = 0; i < oldq->counter; i++)
          q->queries[i] = oldq->queries[i];

}

1) I also tried:

1)我也尝试:

q = oldq;

but this does not work.

但这行不通。

2) I think I have to allocate counter * sizeof(char) space for the queries array but since the struct's member is not a pointer I don't know how to do this.

2)我认为我必须为查询数组分配counter * sizeof(char)空间,但由于struct的成员不是一个指针,我不知道该怎么做。

3 个解决方案

#1


2  

Here you are dealing with a C-style flexible array member. It's not valid C++ code, but it is valid C since C99 (see link for details). To use such structure, you need to allocate sizeof(Queries) + counter bytes, where the array field will use that counter bytes part. (Note: if you had array field other than char you would have to multiply accordingly.)

这里要处理的是c样式的灵活数组成员。它不是有效的c++代码,但是它是有效的C,因为C99(详情请参见链接)。要使用这种结构,需要分配sizeof(查询)+计数器字节,其中数组字段将使用计数器字节部分。(注意:如果你有数组字段而不是char,你就必须相应相乘。)

Now, you cannot use C++ features here like copy constructor since compiler doesn't know the size of your structure. Instead, you have to use the pure C approach:

现在,您不能在这里使用c++特性,比如copy构造函数,因为编译器不知道结构的大小。相反,你必须使用纯C方法:

Queries *cloneQueries(Queries *oldQ)
{
    size_t sizeQ = sizeof(Queries) + oldQ->counter;
    Queries *newQ = (Queries*)malloc(sizeQ);
    memcpy(newQ, oldQ, sizeQ);
    return newQ;
}

#2


2  

The simplest thing to do is to use a std::string for queries.

最简单的方法是对查询使用std::string。

Then you can simply write Queries* q = new Queries(*oldq); and rely on the compiler-generated constructor: you can remove all your copying code.

然后您可以简单地编写查询* q =新查询(*oldq);并且依赖于编译器生成的构造函数:您可以删除所有复制代码。

#3


1  

You could do it by using copy constructor that performs a deep copy of your object.

您可以使用复制构造函数来执行对象的深层拷贝。

This could be done when instead of function() you define a copy constructor like so:

这可以在以下情况下完成:

Queries(const Queries& q)
    : Id(q.Id), from(q.from), counter(q.counter)
{
    // allocate the new memory
    queries = new char[counter];

    // copy each element
    for (size_t i = 0; i < counter; ++i) {
        queries[i] = q.queries[i];
    }
}

and then in your code, you could use the line:

然后在你的代码中,你可以用这行:

Queries *q = new Queries(*oldq); 

where the object on the right hand side is created by copy construction, i.e. by copying the object oldq.

右边的对象是通过复制结构创建的,也就是通过复制对象oldq创建的。


See, how operator new[] works.

看,操作符new[]是如何工作的。

#1


2  

Here you are dealing with a C-style flexible array member. It's not valid C++ code, but it is valid C since C99 (see link for details). To use such structure, you need to allocate sizeof(Queries) + counter bytes, where the array field will use that counter bytes part. (Note: if you had array field other than char you would have to multiply accordingly.)

这里要处理的是c样式的灵活数组成员。它不是有效的c++代码,但是它是有效的C,因为C99(详情请参见链接)。要使用这种结构,需要分配sizeof(查询)+计数器字节,其中数组字段将使用计数器字节部分。(注意:如果你有数组字段而不是char,你就必须相应相乘。)

Now, you cannot use C++ features here like copy constructor since compiler doesn't know the size of your structure. Instead, you have to use the pure C approach:

现在,您不能在这里使用c++特性,比如copy构造函数,因为编译器不知道结构的大小。相反,你必须使用纯C方法:

Queries *cloneQueries(Queries *oldQ)
{
    size_t sizeQ = sizeof(Queries) + oldQ->counter;
    Queries *newQ = (Queries*)malloc(sizeQ);
    memcpy(newQ, oldQ, sizeQ);
    return newQ;
}

#2


2  

The simplest thing to do is to use a std::string for queries.

最简单的方法是对查询使用std::string。

Then you can simply write Queries* q = new Queries(*oldq); and rely on the compiler-generated constructor: you can remove all your copying code.

然后您可以简单地编写查询* q =新查询(*oldq);并且依赖于编译器生成的构造函数:您可以删除所有复制代码。

#3


1  

You could do it by using copy constructor that performs a deep copy of your object.

您可以使用复制构造函数来执行对象的深层拷贝。

This could be done when instead of function() you define a copy constructor like so:

这可以在以下情况下完成:

Queries(const Queries& q)
    : Id(q.Id), from(q.from), counter(q.counter)
{
    // allocate the new memory
    queries = new char[counter];

    // copy each element
    for (size_t i = 0; i < counter; ++i) {
        queries[i] = q.queries[i];
    }
}

and then in your code, you could use the line:

然后在你的代码中,你可以用这行:

Queries *q = new Queries(*oldq); 

where the object on the right hand side is created by copy construction, i.e. by copying the object oldq.

右边的对象是通过复制结构创建的,也就是通过复制对象oldq创建的。


See, how operator new[] works.

看,操作符new[]是如何工作的。