2016-01-08 80 views
1

我已經定義了這樣的結構:複製結構的動態數組到另一個結構

struct Queries { 

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

我所試圖做的是創建一個新的結構「對象」,並從現有的值複製到這個新目的。

我試過

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)我也試過:

q = oldq; 

但這不起作用。

2)我想我必須爲查詢數組分配counter * sizeof(char)空間,但由於結構的成員不是一個指針,我不知道該怎麼做。

+2

如果您定義了正確的副本,您可以使用'查詢* q =新查詢(* oldq);' – Slava

+0

您的想法是正確的。您需要在複製數組之前預分配'counter * sizeof(char)'字節。但是你不需要一個顯式循環來複制它 - 你可以使用'memcpy'。或者,您也可以將其作爲[複製構造函數](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-ree)實現,正如Slava所引用的。 – jweyrich

+0

但是,我應該如何做拷貝構造函數內的數組情況下的賦值? – pirox22

回答

2

這裏您正在處理一個C-style flexible array member。這不是有效的C++代碼,但它自C99以來是有效的C(詳見鏈接)。要使用這種結構,您需要分配sizeof(Queries) + counter字節,其中數組字段將使用該字節部分。 (注意:如果你的數組字段不是char,你必須相應地進行乘法運算。)

現在,你不能在這裏使用C++特性,比如複製構造函數,因爲編譯器不知道你的結構的大小。相反,你必須使用純C的方法:

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

這工作!謝謝 ! – pirox22

2

最簡單的方法是使用std::string代替queries

然後你可以簡單地寫Queries* q = new Queries(*oldq);並依靠編譯器生成的構造函數:你可以刪除你所有的複製代碼。

1

您可以通過使用copy constructor執行你的對象的深拷貝做到這一點。

時,而不是function()定義一個拷貝構造函數,像這樣可以這樣做:

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]; 
    } 
} 

,然後在你的代碼,你可以使用該行:

Queries *q = new Queries(*oldq); 

其中的對象右側是通過複製構建而創建的,即通​​過複製對象oldq


請參閱:how operator new[] works

相關問題