C ++ - интеллектуальные указатели - расположение чтения нарушения доступа 0xDDDDDDDD - PullRequest
0 голосов
/ 27 мая 2019

Я сейчас создаю тест для устаревшего кода и застрял с этим сообщением об ошибке при запуске моего теста (см. Ниже):

Exception thrown at 0x0F5001EF (Control.dll) in sample.exe:
0xC0000005: Access violation reading location 0xDDDDDDDD.

Я понимаю, что 0xDDDDDDDD означает, что код пытался получить доступ к уже удаленному указателю. Но что я не понимаю, так это то, где оно было «преждевременно» удалено.

Я сохранил это до минимума. Вот мой код

CDevice::CDevice() 
{
    numLedRows = numLedCols = 0;
}

CDevice::~CDevice()
{
   std::cout << "destructor!" << std::endl;
}

HRESULT CDevice::Init(IDevice* control)
{
    HRESULT hr = S_OK;
    deviceCtl.reset(control);
    return hr;
}

где:

std::unique_ptr<IDevice>   deviceCtl;

И мой тест:

TEST_F(deviceControlTest, test2)
{
     sut_->Init(deviceMock_.get());
}

, где

std::unique_ptr<CDevice> sut_;
std::unique_ptr<DeviceMock> deviceMock_;

и в SetUp ...

sut_ = std::make_unique<CDevice>();
deviceMock_ = std::make_unique<DeviceMock>();

Я также пытался использовать shared_ptr для DeviceMock, такое же поведение.

Что-то не так с моим кодом? Или это мой тест? Любые предложения будут с благодарностью!

1 Ответ

0 голосов
/ 14 июня 2019

Я думаю, у вас есть проблема двойного удаления: и deviceMock_, и deviceCtl обрабатывают один и тот же указатель. Он удаляется дважды (не имеет значения, если для уникального и общего ptr) один раз, когда вызывается CDevice dtor и его член, включая используемый интеллектуальный ptr, и один раз, когда вызывается deviceControlTest dtor. Обратите внимание, что в gtest порядок вызовов всегда одинаков для каждого теста: ctor набора тестов, настройка набора тестов, тело теста, разборка набора тестов, dtor набора тестов). Опции:

  1. Используйте shared_ptr и скопируйте его внутрь Init (не сбрасывайте его, просто назначьте deviceCtl = control;).
  2. Внедрить через unique_ptr, используя подход из этого вопроса SO.
...