[英]Memory leak in Valgrind using new
The example may be bad but this is how it looks when I trace the stack frame which Valgrind shows.这个例子可能很糟糕,但这是我跟踪 Valgrind 显示的堆栈帧时的样子。 The LocationList, Location, FolderList and Folder are different classes and I have pasted only the copy constructors and assignment operators of these classes. LocationList、Location、FolderList 和 Folder 是不同的类,我只粘贴了这些类的复制构造函数和赋值运算符。 But I am unsure why there is a memory leak.但我不确定为什么会出现内存泄漏。
I understand that I am using new operator and a for loop in copy constructor which could be the cause of trouble but I am unsure how to handle this.我知道我在复制构造函数中使用了 new 运算符和 for 循环,这可能是导致问题的原因,但我不确定如何处理。 Here is the call stack from Valgrind.这是来自 Valgrind 的调用堆栈。
==15733== 8 bytes in 1 blocks are definitely lost in loss record 28 of 1,002
==15733== at 0x4A07152: operator new[](unsigned long) (vg_replace_malloc.c:363)
==15733== by 0x54FA25: FolderList::operator=(FolderList const&) (Folder.h:63)
==15733== by 0x54FD8A: Server::operator=(Server const&) (Server.h:22)
==15733== by 0x550631: Location::operator=(Location const&) (Location.h:44)
==15733== by 0x5507AC: LocationList::LocationList(LocationList const&) (Location.h:76)
==15733== by 0x54988C: VPSyncInterface::login(std::string, std::string, VPStatus*) (vpsync.cc:365)
==15733== by 0x549AD5: VPSyncInterface::connect(std::string, std::string, VPStatus*) (vpsync.cc:382)
==15733== by 0x548FF0: VPSyncInterface::reconnect(VPStatus*) (vpsync.cc:227)
==15733== by 0x548D39: VPSyncInterface::initialize(VPStatus*, int) (vpsync.cc:175)
==15733== by 0x42E5B4: ProcessImageImpl::ProcessImageImpl(char const*, int, char const*, int) (ProcessImageImpl.cc:172)
==15733== by 0x426FDD: cvRetrievalImpl::getProcessObject(cvRetrieval::ProcessType, char const*, int, char const*, int) (cvRetrievalImpl.cc:70)
==15733== by 0x426B4A: main (ThinIMAGEd.cc:727)
Below is the code stack:下面是代码栈:
cvRetrievalImpl.cc
69 case cvRetrieval::PROCESS_IMAGE:
70 return new ProcessImageImpl (application_class, instance_wants_to_access_vp, auth_group, threadCount);
71 break;
ProcessImageImpl.cc
VPStatus init_status;
if (syncInterface->initialize (&init_status) != 0)
{
cvLog (CV_LOG_FATAL, "Cannot initialize VP sync interface: %s",
init_status.interpret_current_status());
exit (EXIT_FAILURE);
}
vpsync.cc
364 LogonXMLParser* parser = new LogonXMLParser ();
365 AddDtd *aDtd = new AddDtd (application_class);
366 string logonOutputXML = aDtd->add (out_xml, process);
367
368 LocationList *vp_locations;
369 vp_locations = parser->doParse ((const XMLByte*) logonOutputXML.c_str (), logonOutputXML.size ());
370 delete aDtd;
378 if (locations)
379 delete locations;
380 // We have to make a private copy of the locations returned by the parser,
381 // because the parser's copy will disappear when the parser is destroyed.
382 locations = new LocationList (*vp_locations);
383 delete parser;
LocationList& operator= (const LocationList& list)
79 {
80 if (this == &list)
81 return *this;
82 incr = list.incr;
83 curr_size = list.curr_size;
84 curr_capacity = list.curr_capacity;
85 if (locations)
86 delete [] locations;
87 locations = new Location[curr_capacity];
88 for (unsigned int i = 0; i < curr_size; i++)
89 locations[i] = list.locations[i];
90 return *this;
91 }
Location.h
39 Location& operator= (const Location& location)
40 {
41 if (this == &location)
42 return *this;
43 locationName = location.locationName;
44 server = location.server;
45 servers = location.servers;
46 return *this;
47 }
Server.h
16 Server& operator= (const Server& server)
17 {
18 if (this == &server)
19 return *this;
20 serverName = server.serverName;
21 folder = server.folder;
22 folders = server.folders;
23 return *this;
24 }
Folder.h
54 FolderList& operator= (const FolderList& list)
55 {
56 if (this == &list)
57 return *this;
58 incr = list.incr;
59 curr_size = list.curr_size;
60 curr_capacity = list.curr_capacity;
61 if (folders)
62 delete [] folders;
63 folders = new Folder[curr_capacity];
64 for (unsigned int i = 0; i < curr_size; i++)
65 folders[i] = list.folders[i];
66 return *this;
67 }
16 Folder& operator= (const Folder& folder)
17 {
18 if (this == &folder)
19 return *this;
20 folderName = folder.folderName;
21 folderDesc = folder.folderDesc;
22 return *this;
23 }
It looks like you have many leaks ( loss record 28 of 1,002
).看起来您有很多泄漏( loss record 28 of 1,002
)。
First, a minor thing.首先,一件小事。 In C++ you don't need to check that a pointer is non-NULL before deleting it.在 C++ 中,您不需要在删除指针之前检查指针是否为非 NULL。 So所以
if (folders)
delete [] folders;
can be replaced by可以替换为
delete [] folders;
Next, you say that you can't use smart pointers.接下来,你说你不能使用智能指针。 It would be even better if you could use standard library containers.如果您可以使用标准库容器,那就更好了。
So instead of defining folders
as a pointer to Folder
and writing因此,而不是将folders
定义为指向Folder
的指针并写入
if (folders)
delete [] folders;
folders = new Folder[curr_capacity];
for (unsigned int i = 0; i < curr_size; i++)
folders[i] = list.folders[i];
you could define std::vector<Folder> folders;
你可以定义std::vector<Folder> folders;
(instead of Folder* folders;
which is what I presume you have currently) and write (而不是Folder* folders;
这是我认为你目前拥有的)并写
folders = list.folders;
Other benefits of this:这样做的其他好处:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.