【发布时间】:2017-02-19 01:50:27
【问题描述】:
以下代码从磁盘读取一个大对象集合(通过 WriteObject 流媒体解压缩的 95G 压缩对象)并将其内容打印为字符串。
object.cxx:
std::vector<char> ObjectHandler::GetObject(const std::string& path)
{
TFile *file = new TFile(path.c_str());
// If file was not found or empty
if (file->IsZombie()) {
cout << "The object was not found at " << path << endl;
}
// Get the AliCDBEntry from the root file
AliCDBEntry *entry = (AliCDBEntry*)file->Get("AliCDBEntry");
// Create an outcoming buffer
TBufferFile *buffer = new TBufferFile(TBuffer::kWrite);
// Stream and serialize the AliCDBEntry object to the buffer
buffer->WriteObject((const TObject*)entry);
// Obtain a pointer to the buffer
char *pointer = buffer->Buffer();
// Store the object to the referenced vector
std::vector<char> vector(pointer, pointer + buffer->Length());
// Release the open file
delete file;
delete buffer;
return vector;
}
main.cxx:
ObjectHandler objHandler;
boost::filesystem::path dataPath("/tmp");
boost::filesystem::recursive_directory_iterator endIterator;
if (boost::filesystem::exists(dataPath) && boost::filesystem::is_directory(dataPath)) {
for (static boost::filesystem::recursive_directory_iterator directoryIterator(dataPath); directoryIterator != endIterator;
++directoryIterator) {
if (boost::filesystem::is_regular_file(directoryIterator->status())) {
cout << directoryIterator->path().string() << endl;
std::vector<char> vector = objHandler.GetObject(directoryIterator->path().string());
cout << vector << endl;
}
}
}
1) 按值调用是实现此方法的正确方法吗?如果通过引用调用,我是否会做额外的副本?
2) 这段代码正在泄漏,我怀疑是 char *pointer 是罪魁祸首,或者是 std::vector 返回的实际 std::vector em>ObjectHandler::GetObject() 方法。我已经使用以下代码测试了实现:
struct sysinfo sys_info;
sysinfo (&sys_info);
cout << "Total: " << sys_info.totalram *(unsigned long long)sys_info.mem_unit / 1024 << " Free: " << sys_info.freeram *(unsigned long long)sys_info.mem_unit/ 1024 << endl;
并且free ram不断减少,直到达到0并且程序被杀死。
【问题讨论】:
-
如果您觉得您的程序内存泄漏,那么您应该尝试一些有助于跟踪的调试工具,例如Massif。请注意,使用这些工具,您的程序运行速度会大大降低。
-
` // 从根文件中获取 AliCDBEntry AliCDBEntry entry = (AliCDBEntry)file->Get("AliCDBEntry");`?
-
每个问题一个问题。
-
离题:除非你有一些看不见的因素强制动态分配文件和缓冲区,否则不要动态分配。
标签: c++ vector memory-leaks std