I have implemented some leak detector of QObjects. To make long story short, During the removing of static objects I check what QObject was not removed. But the problem is that some QObject is allocated staticly so I need to remove them from leak report. Is there are way to know if pointer points to statically allocated object?
-
2What is this leak report? There are a bunch of utilities that already do this, so I wonder if you're re-inventing the wheel. – Christopher Schneider Apr 25 '16 at 14:34
-
1This question is related to: http://stackoverflow.com/q/3065092/694576 if not a duplicate to the latter. – alk Apr 25 '16 at 14:35
1 Answers
AFAIK, there are no portable way to know what duration type a variable uses by simply knowing its address. But provided all your dynamic allocations use new
you could use your own replacement functions for the different signatures of operator new
and operator delete
, and use them to manage a map or a set of all allocations. Reference in current C++ standard draft n4296:
17.6.4.6 Replacement functions [replacement.functions]
...
A C++ program may provide the definition for any of twelve dynamic memory allocation function signatures declared in header <new> (3.7.4, 18.6):
- operator new(std::size_t)
- operator new(std::size_t, const std::nothrow_t&)
- operator new
- operator new[](std::size_t, const std::nothrow_t&)
- operator delete(void*)
- operator delete(void*, const std::nothrow_t&)
- operator delete
- operator delete[](void*, const std::nothrow_t&)
- operator delete(void*, std::size_t)
- operator delete(void*, std::size_t, const std::nothrow_t&)
- operator delete[](void*, std::size_t)
- operator delete[](void*, std::size_t, const std::nothrow_t&)
The program’s definitions are used instead of the default versions supplied by the implementation (18.6). Such replacement occurs prior to program startup (3.2, 3.6). The program’s declarations shall not be specified as inline. No diagnostic is required.
That would allow you to build a kind of hand made valgrind and store for example in an array - usage of standard containers inside operator new could be tedious because they do use operator new! - the list of allocated blocks. At a simple level something like that could help:
// 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
}
Note that I deliberately use C stdio functions for debugging traces to avoid any possibility of C++ allocation memory calls in C++ standard library io.

- 143,923
- 11
- 122
- 252