2016-05-13 3 views
0

Я ввел новый вектор в ранее существовавшую структуру St, которая подобна этому std::vector<X> xInfo; X - это еще одна новая структура с элементами примитивных типов данных. Теперь есть уже существующий код, например memset(&s, 0, sizeof(St));, где s - экземпляр St.. Какую проблему он вызовет из-за добавления вектора xInfo в St?Векторная инициализация в структуре

Как преодолеть проблемы, чтобы я мог сохранить новый вектор внутри структуры?

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

Не рекомендуется использовать memset() для объектов класса, особенно STL-элементов, таких как std :: vector (где вы не знаете, как он построен). Если вы предоставите код, мы можем предложить более полезную обратную связь. Я бы подумал, что 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 содержит зЬй :: вектор, ваш вектор будет топтать этим 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 

ИМХО (я еще не проверил код шаблона вектора) в 24 байт содержит некоторые указатели и накладные расходы. Выведенные указатели указывают на кучу, и ни один из данных не будет в векторном объекте. Stomping with 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]; 
}; 

Все поля данных инициализируется (здесь до 0) во время CTOR. Каждый раз, когда вы создаете экземпляр другого экземпляра, эти ctor обеспечивают инициализацию данных.


... есть ли другое решение ...?

Программное обеспечение является бесконечно гибким, но ctor являются самым простым и самодостаточным документирующим подходом.


Как преодолеть проблемы, так что я могу держать новый вектор внутри структура?

Я не вижу проблемы с сохранением вектора внутри старой структуры. Наиболее подходящий подход - ctor.

+0

Спасибо @ DOUGLAS, я реализовал с таким же подходом. –

Смежные вопросы