Почему деструктор удаления вектора вызывается в результате скалярного удаления?C++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Гость
 Почему деструктор удаления вектора вызывается в результате скалярного удаления?

Сообщение Гость »

У меня есть код, который дает сбой в большой системе.
Однако, по сути, код сводится к следующему псевдокоду.
Я удалил большую часть деталей, как и пытался свести это к минимуму;
Однако я не думаю, что это упускает что-то важное.

Код: Выделить всё

// in a DLL:

#ifdef _DLL
#define DLLEXP __declspec(dllexport)
#else
#define DLLEXP __declspec(dllimport)
#endif

class DLLEXP MyClass // base class; virtual
{
public:
MyClass() {};
virtual ~MyClass() {};

some_method () = 0; // pure virtual

// no member data
};

class DLLEXP MyClassImp : public MyClass
{
public:
MyClassImp( some_parameters )
{
// some assignments...
}

virtual ~MyClassImp() {};

private:
// some member data...
};
и:

Код: Выделить всё

// in the EXE:

MyClassImp* myObj = new MyClassImp ( some_arguments ); // scalar new
// ... and literally next (as part of my cutting-down)...
delete myObj; // scalar delete
Обратите внимание, что используются соответствующие скалярные новые и скалярные удаления.

В сборке отладки в Visual Studio ( 2008 Pro),
в от Microsoft,
не работает следующее утверждение:

Код: Выделить всё

_ASSERTE(_CrtIsValidHeapPointer(pUserData));
В верхней части стопки находятся следующие элементы:

Код: Выделить всё

mydll_d.dll!operator delete()
mydll_d.dll!MyClassImp::`vector deleting destructor'()
Я думаю, так и должно быть

Код: Выделить всё

mydll_d.dll!MyClassImp::`scalar deleting destructor'()
То есть программа ведет себя так, как если бы я написал

Код: Выделить всё

MyClassImp* myObj = new MyClassImp ( some_arguments );
delete[] newObj; // array delete
Адрес в pUserData — это адрес самого myObj (а не члена).
Память вокруг этого адреса выглядит вот так:

Код: Выделить всё

                                ... FD FD FD FD
(address here)
VV VV VV VV MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
FD FD FD FD AB AB AB AB AB AB AB AB EE FE EE FE
...
где четыре VV предположительно являются адресом таблицы виртуальных функций,
MM...MM узнаваем данные-члены,
а остальные байты представляют собой различные специальные маркеры, устанавливаемые отладчиком
(например, FD FD представляют собой «защитные байты» вокруг хранилища объекта).

Незадолго до сбоя утверждения я вижу изменение VV,
и задаюсь вопросом, связано ли это с переключением на таблицу виртуальных функций базового класса.< /p>

Я осознаю проблему того, что разрушается не тот уровень иерархии классов.
Проблема здесь не в этом; все мои деструкторы виртуальные.

Я обращаю внимание на страницу Microsoft
"ОШИБКА: для экспортированного класса вызван неправильный оператор удаления"
http://support. microsoft.com/kb/122675
но, похоже, речь идет о неправильном исполняемом файле (с неправильной кучей), пытающемся взять на себя ответственность за уничтожение данных.

В моем случае дело в том, что применяется неправильный вариант удаления деструктора:
т.е. векторный, а не скалярный.

Я пытаюсь создать минимальный урезанный код, в котором все еще обнаруживается проблема.

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

Возможно, самая большая подсказка здесь — это mydll_d.dll. !operator delete() в стеке.
Должен ли я ожидать, что это будет myexe_d.exe!operator delete(),
указывающее, что DLLEXP имеет «потерялся»?

Полагаю, это может быть случай двойного удаления (но я так не думаю).

Могу ли я прочитать хорошую ссылку о том, что проверяет _CrtIsValidHeapPointer?

Подробнее здесь: https://stackoverflow.com/questions/337 ... lar-delete
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Деструктор PyBind11 не вызывается?
    Anonymous » » в форуме C++
    0 Ответы
    31 Просмотры
    Последнее сообщение Anonymous
  • Почему деструктор должен быть доступен, даже если он не вызывается?
    Anonymous » » в форуме C++
    0 Ответы
    24 Просмотры
    Последнее сообщение Anonymous
  • Почему деструктор глобального объекта вызывается дважды после инициализации ссылки на него?
    Anonymous » » в форуме C++
    0 Ответы
    26 Просмотры
    Последнее сообщение Anonymous
  • Почему деструктор глобального объекта вызывается дважды после инициализации ссылки на него?
    Anonymous » » в форуме C++
    0 Ответы
    15 Просмотры
    Последнее сообщение Anonymous
  • Почему деструктор здесь вызывается дважды?
    Anonymous » » в форуме C++
    0 Ответы
    13 Просмотры
    Последнее сообщение Anonymous

Вернуться в «C++»