2016-05-13 83 views
0

我已經在已有的結構St中引入了一個新的矢量St,就像這樣std::vector<X> xInfo; X是另一個新定義的結構,它包含原始數據類型的成員。現在有一個預先存在的代碼,如memset(&s, 0, sizeof(St));,其中s是St.的一個實例。由於在St中添加了向量xInfo,會導致什麼類型的問題?結構中的矢量初始化

如何克服這些問題,以便我可以在結構中保留新的矢量?

編輯:下面是對形勢

// Below section is new code. 

typedef struct 
{ 
    char m11; 
    int  m12; 
    char m13[50]; 
}X; 
// Below section is existing code. 

typedef struct{ 
    char    m1[10]; 
    int    m2; 
    long    m3; 
    double   m4; 
vector<X>  xInfo; /* this line is newly added code */ 
}St; 

void fun(const char* a1, int a2, long m3, double m4) 
{ 
    St s; 

    memset(&s, 0, sizeof(St)); 

    if(NULL != a1 && 0 != a1[0]) 
     strncpy(m1, a1, 9); 

    m2 = a2; 
    m3 = a3; 
    m4 = a4; 

    ........ 
    ........ 
} 
+1

對於類對象使用memset()並不是一個好主意,特別是像std :: vector(你不知道它是如何構建的)的STL項目。如果您提供代碼,我們可能會提供更多有用的反饋。我認爲memset()可以用於任何POD項目,但通常情況下,分配更容易。請查看[MCVE]。 –

+4

*現在有一個預先存在的代碼,如memset(&s,0,sizeof(St))* - 好了,說白了,是時候改變'memset'代碼了,否則你會在很多悲傷中。 – PaulMcKenzie

+0

@ DOUGLASO.MOEN我在編輯部分添加了代碼示例,請提供解決方案以保留新代碼的現有行爲。除了添加'St'的構造函數外,還有其他解決方案嗎? –

回答

2

這將導致未定義行爲的示例代碼。

翻譯:最有可能是一個崩潰。

1

memset()肯定會混淆你的運行時間。

St s; 
memset(&s, 0, sizeof(St)); 

因爲s包含一個std :: vector的,您的載體將被這個memset的踩踏(),而不是你想要的方式。

正如我在上面的評論中所說的,你做而不是知道如何構建std :: vector <>。例如,在Ubuntu 15.10上,使用g ++ 5.2.1,一個std :: vector <>只有24個字節,而不管有多少個元素。下面是從我的一個小程序的部分輸出:

typedef std::vector<UI224> VecUI224; 
sizeof(VecUI224)    : 24 

VecUI224 vui224; 
sizeof(vui224) : 24 vui224.size() = 000000 vui224.capacity() : 00000 
sizeof(vui224) : 24 vui224.size() = 000001 vui224.capacity() : 00001 
sizeof(vui224) : 24 vui224.size() = 100  vui224.capacity() : 128 
sizeof(vui224) : 24 vui224.size() = 200  vui224.capacity() : 256 
// ... 
sizeof(vui224) : 24 vui224.size() = 900  vui224.capacity() : 1024 
sizeof(vui224) : 24 vui224.size() = 1000  vui224.capacity() : 1024 

IMHO(I尚未檢查的矢量模板代碼)的24個字節包含一些指針和開銷。推斷的指針指向堆,並且沒有數據將存在於矢量對象中。使用memset()跺腳只會破壞向量,X的數據不存在

您現有的memset()只會清除這些向量指針和開銷,而不是數據。可能導致崩潰。

初始化結構(或類)的正確方法是創建一個構造函數,並通過適當的初始值設定項列表賦值。

例1是C風格,並且你確實需要移動到C++:

typedef struct{ 
    char    m1[10]; 
    int    m2; 
    long    m3; 
    double   m4; 
    vector<X>  xInfo; /* this line is newly added code */ 
}St; 

一個可能的C++方法:創建構造函數,添加一個初始化列表。

struct St_t // I use suffix '_t' to indicate a type 
{ 
    St_t (void) : // ctor 
     // m1[10] see body of ctor 
     m2 (0), 
     m3 (0), 
     m4 (0) 
     // xInfo - see default ctor of X_t below 
    { 
     // it is ok to consider this, but raises the wtf factor 
     ::memset(m1, 0, 10); // for the single pod 
    } 
    char    m1[10]; 
    int    m2; 
    long    m3; 
    double   m4; 

    vector<X_t>  xInfo; /* this line is newly added code */ 
}; 

的爲信佛,C++的方法可能是類似以下內容:男星在

struct X_t 
{ 
    X_t(void) : // type X_t default dtor 
     m11(0), 
     m12(0) 
     // m13 
    { 
     // I would fill m13 with 
     for (int i=0;i<50; ++i) 
     m13[i] = 0; 
    } 
    char m11; 
    int  m12; 
    char m13[50]; 
}; 

初始化所有數據字段(這裏爲0)。每當你實例化另一個實例時,這些ctor確保數據被初始化。


...還有沒有其他的解決辦法...?

軟件是非常靈活的,但ctor是最簡單和最自我記錄的方法。


如何克服這些問題,這樣我可以保持新的向量內 結構?

我看到沒有問題保持舊結構中的矢量。 Ctor是最合適的方法。

+0

謝謝@DOUGLAS,我用相同的方法實施。 –