Reputation: 922
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.
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:
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.
Upvotes: 1
Views: 1275
Reputation: 1362
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.)
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:
Queries *cloneQueries(Queries *oldQ)
{
size_t sizeQ = sizeof(Queries) + oldQ->counter;
Queries *newQ = (Queries*)malloc(sizeQ);
memcpy(newQ, oldQ, sizeQ);
return newQ;
}
Upvotes: 2
Reputation: 6477
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
.
See, how operator new[]
works.
Upvotes: 0
Reputation: 234875
The simplest thing to do is to use a std::string
for queries
.
Then you can simply write Queries* q = new Queries(*oldq);
and rely on the compiler-generated constructor: you can remove all your copying code.
Upvotes: 2