Перегружен оператор new при наличии макроса DEBUG_NEW - PullRequest
0 голосов
/ 10 марта 2020

В проекте MF C я использую внешнюю библиотеку TTL , которая перегружает operator new. Моя проблема в том, что у меня есть утечка памяти, и я хотел бы использовать диагностику, заданную DEBUG_NEW. Однако я могу скомпилировать это только с DEBUG_NEW закомментированным, иначе я получаю ошибку ниже.

Это демонстрирует следующее. Это MCVE, когда проект Visual Studio выполнен в виде консольного приложения с заголовками MF C .

// The problem is when this is uncommented
#ifdef _DEBUG
#define new DEBUG_NEW
#endif

struct HandleId
{
  HandleId() {}

  void* operator new (size_t t) {
    return HandleId::operator new(t, 0, 0, 0);
  };
  void* operator new (size_t t, int, const char* file, int line) {
    HandleId* tmp = (HandleId*)calloc(1, t);
    return tmp;
  };
  void operator delete (void* v) {
    free(v);
  }
};

namespace hed
{
  struct Node : public virtual HandleId
  {
    Node() {};
    Node(double x, double y, double z = 0.0) {}
  };
}

struct DtmNode : public hed::Node
{
  DtmNode() {};
  DtmNode(short pntRef, double x, double y, double z)
    : hed::Node(x, y, z)
  {};
};

int main()
{
  DtmNode* pNode = new DtmNode(0, 1.0, 2.0, 3.0);
  return 0;
}

с комментариями DEBUG_NEW вышеупомянутая компиляция завершается неудачно (VS2019) с .

ошибка C2661: HandleId::operator new: ни одна перегруженная функция не принимает 3 аргумента

До сих пор я жил с закомментированным макросом. Но я теперь делаю хочу его в отладочных сборках по очевидной причине, помогающей отлавливать утечки памяти во время отладки. DtmNode это мой класс, который я могу изменить. HandleId и пространство имен hed принадлежат библиотеке.

Мой вопрос:

  1. Есть ли способ скомпилировать это с DEBUG_NEW без комментариев?
  2. В качестве альтернативы, есть ли способ сказать DtmNode не использовать перегруженный operator new в режиме _DEBUG, чтобы DEBUG_NEW использовался в соответствии с "нормальным"?

1 Ответ

0 голосов
/ 10 марта 2020

Ответ на ваш первый вопрос - «нет».

Вы можете скомпилировать подобные вещи, выборочно отменяя определение, используя #pragma push_macro / pop_macro:

#ifdef _DEBUG
#define new DEBUG_NEW
#endif
...
int main()
{
#pragma push_macro("new")
#undef new
  DtmNode* pNode = new DtmNode(0, 1.0, 2.0, 3.0);
#pragma pop_macro("new");

  return 0;
}

Он выиграл не позволяет вам отслеживать объекты из библиотеки, используя распределитель отладки MF C (для этого вам придется полностью заменить распределитель библиотеки). Но это как минимум позволит вашей программе работать при наличии несоответствующего оператора new.

...