Ни один из других ответов не объясняет, что делает компилятор. Я постараюсь объяснить.
Когда вы вызываете malloc
, программа резервирует некоторое пространство памяти для структуры. Это пространство заполнено мусором памяти (то есть случайными числами вместо полей структуры).
Теперь рассмотрим этот код:
// (tested on g++ 5.1.0 on linux)
#include <iostream>
#include <stdlib.h>
struct S {
int a;
};
int main() {
S* s = (S*)malloc(sizeof(S));
s->a = 10;
*((int*)s) = 20;
std::cout << s->a << std::endl; // 20
}
Таким образом, при доступе к элементу структуры вы на самом деле получаете доступ к позиции в памяти, не должно быть неожиданным при записи в него.
Но в C ++ вы можете перегружать операторы. Теперь представьте, что произойдет, если перегруженному оператору присваивания потребуется инициализация класса, как показано в коде ниже:
// (tested on g++ 5.1.0 on linux)
#include <iostream>
#include <stdlib.h>
class C {
public:
int answer;
int n;
C(int n) { this->n = n; this->answer = 42; }
C& operator=(const C& rhs) {
if(answer != 42) throw "ERROR";
this->n = rhs.n; return *this;
}
};
struct S {
int a;
C c;
};
int main() {
S* s = (S*)malloc(sizeof(S));
C c(10);
C c2(20);
c = c2; // OK
std::cout << c.n << std::endl; // 20
s->c = c; // Not OK
// Throw "ERROR"
std::cout << s->c.n << std::endl; // 20
}
Когда выполняется s->c = c
, оператор присваивания проверяет, является ли s->c.answer
значением 42
, в противном случае выдает ошибку.
Таким образом, вы можете сделать только то, что сделали в своем примере, если знаете, что перегруженный оператор присваивания класса std::vector
не ожидает инициализированный вектор. Я никогда не читал исходный код этого класса, но держу пари, что он ожидает.
Так что это не рекомендуется делать, но это не невозможно сделать с безопасностью, если вам действительно нужно. Вам просто нужно убедиться, что вы знаете поведение всех используемых вами операторов присваивания.
В вашем примере, если вам действительно нужна std::vector
в структуре, вы можете использовать векторный указатель:
class MyClass { ... };
struct S {
std::vector<MyClass>* vec;
}
int main() {
S s;
MyClass c;
s.vec = new std::vector<MyClass>();
s.vec->push_back(c);
}