2016-10-10 13 views
-4

次のコードは、大きなオブジェクトコレクション(WriteObjectストリーマを使用して圧縮されていない圧縮オブジェクトの95G)をディスクから読み取り、その内容を文字列として出力します。C++ char * + std :: vector memory leak

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 *ポインタいずれか責任があることを疑い、またはObjectHandlerによって返される実際ののstd ::ベクトル ::の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; 

し、それが0に達すると、プログラムが殺されるまで、自由ラムが連続して減少しています。

+0

あなたのプログラムがメモリをリークしていると感じたら、[Massif](http://valgrind.org/info/tools.html#massif)のような、それを追跡するのに役立つデバッグツールを試してみるべきです。これらのツールを使用すると、プログラムがかなり遅く実行されることに注意してください。 –

+0

'//ルートファイルからAliCDBEntryを取得する AliCDBEntry * entry =(AliCDBEntry *)file-> Get(" AliCDBEntry ");'? – kfsone

+0

質問ごとに1つの質問。 –

答えて

1

「メモリリーク」とは、いくつかのことを含む用語です。あなたが話している人に応じて。 1つは一致する削除のない新しいものです。 もう1つは、しばしば参照され、範囲内で参照されているが使用されていない、または必要でないメモリです。

プロフィラーを使用していない場合は、あなたが持っているものを確かめることはできませんが、大規模なベクターが渡されているため、あなたが何をするのかわからない場合は、誰も目にすることはないでしょう。