2016-05-13 9 views
0

私は既存の構造Stに新しいベクトルを導入しました。これはstd::vector<X> xInfo;のようなものです。Xはプリミティブ型のメンバーを持つ新たに定義された構造体です。現在、memset(&s, 0, sizeof(St));のような既存のコードがあります。ここでsはSt.のインスタンスです。ベクトルxInfoStに追加すると、どのようなタイプの問題が発生しますか?構造内のベクトルの初期化

構造内に新しいベクターを保持できるように、問題を解決するにはどうすればよいですか?

EDIT:以下は、これは未定義の動作になります状況

// 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

クラスオブジェクト、特にstd :: vector(どのようにビルドされているのかわからない)のようなSTL項目に対してmemset()を使用することはお勧めできません。コードを提供すれば、より有用なフィードバックを提供するかもしれません。私はmemset()は任意のPODアイテムで使用できると思いますが、通常は代入が簡単です。 [MCVE]を確認してください。 –

+4

* memset(&s、0、sizeof(St))*のような既存のコードがあります。*まあ、明示的に言えば、あなたは 'memset'コードを変更する必要があります。多くの悲しみのために。 – PaulMcKenzie

+0

@ DOUGLASO.MOEN EDITセクションにコード例を追加しました。新しいコードで既存の動作を保持するソリューションを提案してください。 'St'のコンストラクタを追加する以外に、他の解決策がありますか? –

答えて

2

のためのサンプルコードです。

翻訳:おそらくクラッシュします。

1

memset()はあなたのランタイムを間違いなく混乱させます。

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

sにはstd :: vectorが含まれているため、ベクトルはこのmemset()によってストンプされます。

私は上記の私のコメントで言ったように、あなたははないのstd ::ベクトル<>が構築されている方法を知っています。たとえば、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 

私見(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++アプローチ:初期化リストを追加し、ctorのを作成します。

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 */ 
}; 

XINFOためのザ・、C++のアプローチは、次のようなものかもしれません:ctorの中に(ここでは0)に初期化さ

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

すべてのデータフィールド。 別のインスタンスをインスタンス化すると、これらのctorによってデータが確実に初期化されます。


...他の解決策はあり...?

ソフトウェアは無限に柔軟性がありますが、ctorは最も簡単で最も自己記述的なアプローチです。私は 構造内の新しいベクトルを保つことができるように課題を克服する方法


古い構造体の内部にベクトルを保持することは問題ありません。 ctorが最も適切なアプローチです。

+0

ありがとう@DOUGLAS、私は同じアプローチで実装しました。 –

関連する問題