Strange memory allocation issues?
-
Hey
A bit confused here :- )
QT6.5I have as my test utils >
std::atomic<size_t> allocations = 0; std::atomic<size_t> deallocations = 0; std::atomic<size_t> badAllocs = 0; std::atomic<int64_t> totalSizeAllocated; std::atomic<int64_t> totalBadAllocs; int64_t total = 0; std::atomic<bool> mRecordData = true; void *operator new(std::size_t size) { if (mRecordData) { allocations++; total++; void *p = std::malloc(size); if (!p) { badAllocs++; totalBadAllocs += size; return p; } totalSizeAllocated += size; return p; } else { void *p = std::malloc(size); return p; } } void operator delete(void *p) noexcept { if (mRecordData) { deallocations++; total--; } std::free(p); } void startAllocation() { allocations = 0; deallocations = 0; total = 0; badAllocs = 0; totalSizeAllocated = 0; mRecordData = true; } void endAllocations() { mRecordData = false; EXPECT_EQ(allocations, deallocations); EXPECT_EQ(total, 0); std::cout << "Total Size Allocated: " << totalSizeAllocated << std::endl; if (badAllocs) { std::cout << "BAD ALLOCS !!! : " << badAllocs << " ||| " << totalBadAllocs << std::endl; } }
And as test I have >
startAllocation(); { QString s = "csacsa"; auto s2 = std::string("Hello"); auto sutf = s.toUtf8(); auto s3 = sutf.toStdString(); // memory leak??? auto s4 = s.toStdString(); // memory leak??? } endAllocations();
testLog
allocations Which is: 1 deallocations Which is: 3 total Which is: -2 0 Total Size Allocated: 16
Any idea why converting QString to stdString causes memory allocation issues?
Edit1
Strange enough if I do this >
auto ah = std::string{sutf.data(), (unsigned __int64) sutf.size()};
auto ah2 = std::string{s2 .toUtf8().data(), (unsigned __int64) s2.size()};
no allocations issues? O.O -
@Dariusz said in Strange memory allocation issues?:
Any idea why converting QString to stdString causes memory allocation issues?
I don't know what you're trying to achieve - if you want to look for memory leaks use the appropriate tools but those two functions don't leak any memory.
/edit:
and btw: there is more than one new operator: https://en.cppreference.com/w/cpp/memory/new/operator_new -
@Christian-Ehrlicher Oh snap. So I have to wrapp all of new allocators/deallocators to properly track it. Ahhhhhhhh my bad, off to add more !
Thanks for ping!
Will be back after further testing. -
@Christian-Ehrlicher said in Strange memory allocation issues?:
@Dariusz said in Strange memory allocation issues?:
Any idea why converting QString to stdString causes memory allocation issues?
I don't know what you're trying to achieve - if you want to look for memory leaks use the appropriate tools but those two functions don't leak any memory.
/edit:
and btw: there is more than one new operator: https://en.cppreference.com/w/cpp/memory/new/operator_newMeh no luck, added other ones but failed to track it :/
// 1. Simple allocation void *operator new(std::size_t size) { if (mRecordData) { allocations++; total++; void *p = std::malloc(size); if (!p) { badAllocs++; totalBadAllocs += size; throw std::bad_alloc(); } totalSizeAllocated += size; return p; } return std::malloc(size); } // 2. Array allocation void *operator new[](std::size_t size) { return ::operator new(size); } // 3. No-exception allocation void *operator new(std::size_t size, const std::nothrow_t &) noexcept { if (mRecordData) { allocations++; total++; void *p = std::malloc(size); if (!p) { badAllocs++; totalBadAllocs += size; } return p; } return std::malloc(size); } // 4. Array no-exception allocation void *operator new[](std::size_t size, const std::nothrow_t &nt) noexcept { return ::operator new(size, nt); } #if __cplusplus >= 201703L // 5. Aligned allocation (C++17 onward) void *operator new(std::size_t size, std::align_val_t al) { if (mRecordData) { allocations++; total++; void *p = _aligned_malloc(static_cast<size_t>(al), size); if (!p) { badAllocs++; totalBadAllocs += size; throw std::bad_alloc(); } totalSizeAllocated += size; return p; } return _aligned_malloc(static_cast<size_t>(al), size); } // 6. Aligned array allocation (C++17 onward) void *operator new[](std::size_t size, std::align_val_t al) { return ::operator new(size, al); } #endif // Corresponding delete overloads void operator delete(void *p) noexcept { if (mRecordData) { deallocations++; total--; } std::free(p); } void operator delete[](void *p) noexcept { ::operator delete(p); } void operator delete(void *p, const std::nothrow_t &) noexcept { ::operator delete(p); } void operator delete[](void *p, const std::nothrow_t &) noexcept { ::operator delete(p); } #if __cplusplus >= 201703L void operator delete(void *p, std::align_val_t) noexcept { ::operator delete(p); } void operator delete[](void *p, std::align_val_t) noexcept { ::operator delete(p); } #endif
Bummer!
Just wanted a lightweight way of tracking my test allocations/memory footpring :c
I know there is valgrind/other ones, but they are harder to set up for per-function tests/etc inside gtest as far as I can tell :/