简体   繁体   中英

Detected memory leaks in c++

The following declaration in the file generated by grpc (grpc.pb.cc) causes a memory leak. It seems that google::protobuf::ShutdownProtobufLibrary() does not free the memory allocated by this declaration. Would you tell me how to release it?

PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_DxpGrpc_2eproto(&descriptor_table_DxpGrpc_2eproto);

Windows, C ++, gRPC-1.40.0

Create a console application in the Windows c++ environment and execute the following code.

#include <crtdbg.h>.
#include "google/protobuf/service.h";

int main(int argc, char** argv) {
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    google::protobuf::ShutdownProtobufLibrary();
    return 0;
}

The following leaks will be out.

Detected memory leaks!
Dumping objects -> {159}
{Normal block at 0x00E49B18, 8 bytes long.
 Data: < k > 10 6B C9 00 00 00 00 00 
Object dump complete.

When declare AddDescriptorsRunner in grpc.pb.cc, it calls DefaultConstruct() of the following class.

(File: third_party\protobuf\src\google\protobuf\message_lite.h)

template <typename T>.
class ExplicitlyConstructed {
 public:
  void DefaultConstruct() { new (&union_) T(); }
  template <typename... Args>
  void Construct(Args&&... args) {
    new (&union_) T(std::forward<Args>(args)...) ;
  }

  void Destruct() { get_mutable()->~T(); }

  constexpr const T& get() const { return reinterpret_cast<const T&>(union_); }
  T* get_mutable() { return reinterpret_cast<T*>(&union_); }

 private:
  // Prefer c++14 aligned_storage, but for compatibility this will do.
  union AlignedUnion {
    alignas(T) char space[sizeof(T)];
    int64 align_to_int64;
    void* align_to_ptr;
  } union_;
};

The static data or global object is freed the very last thing, after atexit , and the debugger reports false leak. This behavior can be reproduced with this example:

#include <Windows.h>
std::string str;
int main() 
{
    _CrtDumpMemoryLeaks();//str is not freed yet
    return 0;
}

You can create a structure and place the leak report in the destructor, as shown below. Note in this example, std::string str; is used to cause a leak report.

If cleanup is not defined, or if cleanup is defined after std::string str; then false leak is reported. The order of definition matters.

#include <iostream>
#include <string>
#include <Windows.h>

struct cleanup_t
{ 
    ~cleanup_t() { if(IsDebuggerPresent()) _CrtDumpMemoryLeaks(); }
} cleanup;

std::string str;

int main() 
{
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM