【问题标题】:How to use overloaded new operator used in QT namespace如何使用 QT 命名空间中使用的重载 new 运算符
【发布时间】:2011-11-30 07:31:44
【问题描述】:

我正在编写一个使用 QT 库的 C++ 应用程序。我想检测我的应用程序和 QT 中的内存泄漏。因此,我使用此引用 http://lists.trolltech.com/qt-interest/2002-04/msg00933.html 重载了 main.cpp 中的 new 和 delete 运算符,但 QT 没有使用重载的运算符。显然,这似乎是一个命名空间问题。如何解决这个问题。

int numAllocUnits = 0;
ofstream myLogFile("/root/memLeak.log");

class MemoryLeak_Manav
{
public:
        MemoryLeak_Manav() {
        if (!myLogFile.is_open()) {
                cout << "Unable to open file";
        }
        myLogFile << "Memory Leak Detection log File" << endl;
        printf("Memory Leak Detection On ... ");
        }

public:
        ~MemoryLeak_Manav() {
        myLogFile.close();
        if(numAllocUnits)
                printf("\nError: Memory leak detected: %d\n\n", numAllocUnits);
        else printf("\nNo memory leak detected.\n\n");
        }

public:
   void *operator new [] (size_t size);
   void *operator new (size_t size);
   void operator delete [] (void *p);
   void operator delete (void *p);
};

void * MemoryLeak_Manav::operator new(size_t size)
{
  void *newPtr;
  numAllocUnits++;
  newPtr = malloc(size);
  printf("malloc [%p allocated %d bytes]\n", newPtr, size);
  myLogFile << "malloc [" << newPtr << "allocated" << size << "bytes" << endl;
  return newPtr;
}

void  MemoryLeak_Manav::operator delete(void *p)
{
  numAllocUnits--;
  free(p);
}

void * MemoryLeak_Manav::operator new [] (size_t size)
{
  void *newPtr;
  numAllocUnits++;
  newPtr = malloc(size);
  printf("malloc [%p allocated %d bytes]\n", newPtr, size);
  myLogFile << "malloc [" << newPtr << "allocated" << size << "bytes" << endl;
  return newPtr;
}

void  MemoryLeak_Manav::operator delete [] (void *p)
{
  numAllocUnits--;
  printf("free %p\n", p);
  myLogFile << "free" << p << endl;
  free(p);
}

memLeak.log 文件是空的,我也没有看到任何 printf 的消息。

【问题讨论】:

  • 您不需要使用新的运算符重新编译所有 Qt 库以使其正常工作吗?

标签: c++ qt memory-leaks operator-overloading new-operator


【解决方案1】:

您不能在库中重载 new,因为库已经编译。要在 Qt 中替换 new,您必须获取 Qt 源代码,将重载放在它们的任何基本文件中,然后重新编译。顺便说一句,这并不像听起来那么难。

【讨论】:

    【解决方案2】:

    您使您的操作员成为一个班级的成员。像这样,它们只会在类的命名空间内使用。

    只需将运算符定义为全局运算符(没有类)就可以了

    【讨论】:

    • 当我将其作为全局运算符时,它将影响所有库。这样做时我得到了 SIGSEGV。
    • 那么重新编译 Qt 是你唯一的机会
    • SIGSEGV 来自 libstdc++Starting 程序:/tuxedo -qws [使用 libthread_db 启用线程调试] [新线程 1073878160 (LWP 5916)] malloc [0x87a008 分配 4 个字节] 程序收到信号 SIGSEGV,分段故障。 [切换到线程 1073878160 (LWP 5916)] 0x41359ea0 in std::ostream::sentry::sentry () from /lib/libstdc++.so.6 (gdb)
    【解决方案3】:

    如果你可以在 Linux 上测试它,那么看看使用Valgrind Memcheck 工具。

    这提供了有关泄漏和不良内存使用(双重释放、损坏、部分释放)的非常详细的信息,包括完整的堆栈跟踪。

    【讨论】:

    • 我使用的是 Linux,但我需要为不支持 Valgrind 的 ARM-v6 进行交叉编译。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-04
    • 2010-09-15
    • 2011-12-03
    • 2019-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多