结构中的矢量初始化

Vector initialization in a structure

本文关键字:初始化 结构      更新时间:2023-10-16

我在一个预先存在的结构St中引入了一个新的向量,就像这个std::vector<X> xInfo; X是另一个新定义的结构,具有基元数据类型的成员。现在有一个预先存在的代码,如memset(&s, 0, sizeof(St));,其中s是St的一个实例。由于将向量xInfo添加到St中,它会引起什么类型的问题?

如何克服这些问题,以便将新向量保留在结构中?

编辑:以下是情况的示例代码

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

这将导致未定义的行为。

翻译过来就是:很可能是崩溃。

memset()肯定会混淆您的运行时。

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

因为s包含一个std::vector,所以你的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(我还没有检查矢量模板代码)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++方法可能如下所示:

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期间初始化了所有数据字段(此处为0)。任何时候实例化另一个实例时,这些ctor都会确保数据初始化。


还有其他解决方案吗。。。?

软件是无限灵活的,但ctor是最简单、最自我记录的方法。


如何克服这些问题,以便将新矢量保留在内部结构?

我认为将向量保留在旧结构中没有问题。ctor是最合适的方法。