Сбой сравнения указателей NULL - PullRequest
2 голосов
/ 01 апреля 2010

Я инициализирую в классе указатель на NULL. После этого я проверяю, имеет ли он значение NULL в том же классе. Но это не всегда 0x0. Иногда это 0x8 или 0xfeffffff или 0x3f800000 или 0x80 или другие странные вещи. В большинстве случаев указатель равен 0x0, но иногда он каким-то образом изменяется.

Я уверен, что я нигде не изменяю это в своем коде. Есть ли способ, которым это меняется "собой"?

Вот мой код:

MeshObject::MeshObject()
{
    mesh.vertexColors = NULL;
}

MeshObject::MeshObject(const MeshObject &_copyFromMe)
{
    SimpleLog("vertexColors pointer: %p", _copyFromMe.mesh.vertexColors);
    if (_copyFromMe.mesh.vertexColors != NULL)
    {
        SimpleLog("vertexColors");
        this->mesh.vertexColors = new tColor4i[_copyFromMe.mesh.vertexCount];
        memcpy(this->mesh.vertexColors, _copyFromMe.mesh.vertexColors, _copyFromMe.mesh.vertexCount * sizeof(tColor4i) );
    }
}

Мое приложение падает, потому что vertexColors не был инициализирован и копируется. Однако это NULL и не должно копироваться.

Спасибо.

Ответы [ 5 ]

11 голосов
/ 01 апреля 2010

Это:

MeshObject::MeshObject(const MeshObject &_copyFromMe)

является конструктором копирования. Поскольку это конструктор, он также должен устанавливать для члена vertexColors какое-то известное и, надеюсь, допустимое значение, но это не так, если только значение в копируемой вещи не равно NULL. Но что если это NULL? По сути, ваш if () нуждается в else.

6 голосов
/ 01 апреля 2010

Код неполный, но я могу сделать одно предположение.

Когда вы создаете объект класса MeshObject с использованием вышеупомянутого конструктора копирования и исходный объект имеет NULL в mesh.vertexColors, новый объект mesh.vertexColors будет содержать мусор, потому что не инициализировать его вообще.

Например

MeshObject a;
// `a.mesh.vertexColors` is NULL

MeshObject b = a;
// `b.mesh.vertexColors` is garbage

Вам необходимо инициализировать mesh.vertexColors в конструкторе копирования во всех случаях, а не только когда источник не равен нулю.

3 голосов
/ 01 апреля 2010
MeshObject o1;      // vertexColor is NULL
MeshObject o2(o1);  // vertexColor is undefined
MeshObject o3(o2);  // BOOM!
2 голосов
/ 01 апреля 2010

По сути, когда вызывается ваш конструктор копирования, он не вызывает нормальный конструктор. Конструктор копирования должен инициализировать указатель на NULL так же, как обычный конструктор. Иначе, оно имеет случайное значение, потому что вы используете неинициализированную память. Приличный компилятор должен давать вам предупреждение или ошибку об этом.

1 голос
/ 01 апреля 2010

В дополнение к тому, что сказали другие, как правило, я инициализирую все члены в конструкторе копирования, который я инициализировал в конструкторе без копирования, если нет веской причины не делать этого. И я не могу вспомнить, когда в последний раз была такая причина.

...