2016-04-25 2 views
0

Я реализовал некоторые течеискатели QObjects. Короче говоря, во время удаления статических объектов я проверяю, какой QObject не был удален. Но проблема в том, что некоторые QObject выделяются статически, поэтому мне нужно удалить их из отчета об утечке. Есть ли способ узнать, указывает ли указатель на статически выделенный объект?Проверьте, указывает ли указатель на статически выделенный объект?

+2

Что это за сообщение об утечке? Есть куча утилит, которые уже делают это, поэтому я задаюсь вопросом, не изобретаете ли вы колесо. –

+1

Этот вопрос связан с: http://stackoverflow.com/q/3065092/694576, если не дубликат последнего. – alk

ответ

2

AFAIK, нет портативного способа узнать, какой тип продолжительности используется переменной, просто зная его адрес. Но при условии, что все ваши динамические распределения используют new, вы можете использовать свои собственные функции замены для разных подписей operator new и operator delete и использовать их для управления картой или набором всех распределений. Упоминание в текущем стандарте C++ проект n4296:

17.6.4.6 функции замены [replacement.functions]

... Программа
C++ может обеспечить определение для любого из двенадцати динамической памяти сигнатуры функций распределения объявленная в заголовке < новый > (3.7.4, 18.6):

  • оператора новый (станд :: size_t)
  • оператор пе ш (Std :: size_t, Const станд :: nothrow_t &)
  • оператора новый
  • оператора новый [] (Std :: size_t, Const станд :: nothrow_t &)
  • оператор удаления (недействительными *)
  • оператор удаления (пустота *, Const станд :: nothrow_t &)
  • оператор удаления
  • оператор удаления [] (недействительными *, Const станд :: nothrow_t &)
  • оператор удаления (аннулируются *, станд :: size_t)
  • оператор удаления (аннулируются *, станд :: size_t, Const станд :: nothrow_t &)
  • оператор удаления [] (недействительными *, станд :: size_t)
  • оператор удаления [] (недействительными *, станд: : size_t, Const станд :: nothrow_t &)

определение этой программы используется вместо версий по умолчанию, поставляемой реализация (18,6). Такая замена происходит до запуска программы (3.2, 3.6). Декларации программы не должны быть , указанными как встроенные. Диагностика не требуется.

Это позволит вам построить свой род ручного Valgrind и хранить, например, в массиве - использование стандартных контейнеров внутри оператора нового может быть утомительным, потому что они используют оператор новый! - список выделенных блоков. На простом уровне что-то подобное, что может помочь:

// use a SZ value big enough for your program... 
#define SZ 1000 
struct Alloc { 
    void *p; 
    size_t size; 
} alloc[SZ]; 

bool inited = false; 

void * operator new(size_t s) { 
    void * p = malloc(s); 
    if (p != NULL) { 
     // fprintf(stderr, "Allocate %d at %p\n", s, p); // for debug 
     for (int i=0; i<SZ; i++) { 
      if (alloc[i].p == NULL) { 
       alloc[i].p = p; 
       alloc[i].size = s; 
       break; 
      } 
     } 
    } 
    return p; 
} 

void operator delete(void *p) { 
    size_t s = 0; 
    if (p != NULL) { 
     for (int i=0; i<SZ; i++) { 
      if (alloc[i].p == p) { 
       s = alloc[i].size; 
       alloc[i].p = NULL; 
       break; 
      } 
     } 
     free(p); 
    } 
    // fprintf(stderr,"De-allocate %p (%d)\n", p, s); // for debug 
} 

Обратите внимание, что я намеренно использовать функции Си STDIO для отладки прослеживает, чтобы избежать любой возможности распределения памяти C++ вызывает в стандартной библиотеке C++ гипергликемии.

Смежные вопросы