Вот пример кода:
class IntWrapper
{
public:
IntWrapper(int value_ = 0): value(value_) {}
int getNumber()
{
return value;
}
void setNumber(int value_)
{
value = value_;
}
private:
int value;
};
class T
{
public:
T(){}
void test()
{
std::cout << ptr->getNumber() << std::endl;
ptr->setNumber(10);
std::cout << ptr->getNumber() << std::endl;
}
private:
IntWrapper *ptr;
};int main( int argc, char* argv[] )
{
T t;
t.test(); // may cause segmentation fault
return 0;
}
ptr это свисающий указатель. Когда я запускаю эту программу, она печатает:
1
10
но это также может вызвать ошибку сегментации (даже если вызывается только функция, которая читает память — getNumber).
Поскольку ptr никогда не инициализируется, он может указывать на что угодно — код, данные, стек, не отображенную память, память, которая отображается, но не находится в диапазоне использования. То есть адрес в переменной-члене ptr может содержать случайные оставшиеся данные, специальные значения, сгенерированные компилятором или реализацией кучи, или ???
Рассуждения о том, почему вы получаете или не получаете ошибку сегментации в этих обстоятельствах, не особенно полезны или значимы в большинстве случаев. Просто не делай этого. Это «неопределенное поведение» и может привести к непредсказуемым последствиям.
Других решений пока нет …