0

背景: ファイルからデータを読み込むためのコードに取り組んでいます。データの例は改行で区切られています。また、データにはメタレベルがあり、セミコロンは区切り文字として機能し、シーケンスの終わりに達したことを示します。ファイルには多くのシーケンスが含まれています。ファイルを開き、データの行を読み取ってベクトルとして保存し、データを処理してから、次の行を読み取ります...ファイルの終わりまで。

以下は正常にコンパイルされ、私の Linux マシンで valgrind を使用して実行すると、メモリ リークは見つかりません。しかし、研究室の Windows マシンで Parallel Studio の c++ インスペクタ ツールを使用すると、プログラムのメモリ関連のエラーが両方ともこのファイルに報告されます。

メモリ リークが報告されており、次の行に起因しているようです。

    ss>>number;

また、次のようなカーネル リソース リークも報告されています。

    data.open(filename.c_str());

これらのエラーが発生する理由と、それらを修正するために何をすべきかを理解できる人はいますか? これがメモリ リークである理由がわかりません。また、カーネル リソース エラーについても確信が持てません。また、私がここでとんでもない愚かなことをしている場合は、遠慮なくお知らせください。

class Network;

namespace data {
static std::string trainfiles[] = {
"/home/samurain/htm_check/data_files/train/sequence1.train", 
"/home/samurain/htm_check/data_files/train/sequence2.train"};

static std::string testfiles[] = {
"/home/samurain/htm_check/data_files/train/sequence1.train", 
"/home/samurain/htm_check/data_files/train/sequence2.train"};
}

const char SEQ_DELIM = ';'; 

struct Example
{
std::vector<int> stimulus;
std::fstream data;

bool clear() {stimulus.clear();} 

bool open_file(std::string & filename)
{
data.open(filename.c_str());
if (!data)
    {
        std::cout <<"error opening file\n";
        return false;
    }
std::cout<<"opening file... " <<filename <<" opened \n";
return true;
}

bool close_file()
{
std::cout<<"closing file... ";
data.close(); data.clear();
std::cout<<"closed\n";
return true;
}

bool read_next(Network * myNetwork, bool & new_seq)
{
if (!data)
{
    std::cout<<"file not opened" <<std::endl;
    return false;
}

if (data.peek() == SEQ_DELIM)
{
    data.ignore(100,'\n');
    myNetwork->clearStates();
    new_seq = true;
}

int number = 300; //assuming input will be integer values, not set to 0 for debugging purposes

std::string line;   

getline(data, line);

if (!data.good())
{
    std::cout<<"end of file reached" <<std::endl;
    return false;
}

std::stringstream ss(line);
while (ss)
{
    ss>>number;
    if (ss.good())
    {
        stimulus.push_back(number);
    }
}
return true;    
}//end read next
};//end of Example
4

1 に答える 1

0

おそらく、Parallel Studioが不満を言っているのは、基本的なファイル操作(開く、閉じる、読み取る)をクラスのすべてのユーザーに公開し、クラスを少しのデータ検証を伴うExampleややぎこちないラッパーにすぎないことです。 std::fstream。特に、あなたはそのユーザーに正しい方法でExample電話openをかけることを強制していません。close

これは非常に異なるツールであるため、valgrindを気にする必要はありません。Valgrindは、実行中のプログラムを監視して、メモリリークやカーネルリソースなどの愚かなことを行わないようにします。おそらく、そうはなりません。PSは、リソースのリークを可能にしたかどうかを確認するために、ある種の静的分析を実行しています。この場合は、リークを実行しました(実際にこの可能性を悪用していなくても)。

このクラスをもっとC++っぽく書き直します。特に、open_file()いつでも呼び出すことができるメソッドではなく、コンストラクターである必要があります。close_file()単なるランダムな方法ではなく、同等にデストラクタである必要があります。これは、オブジェクト自体がリークされない限り、カーネルリソースが(通常は)リークされないというParallel Studioを満足させる必要があります(おそらく他の場所の可能性をキャッチしますが、いずれにせよ、オブジェクト全体がリークされた場合、それはクラスのものではありません障害)。

PSがメモリリークについて何について不平を言っているのかわからない。その線は私にはうまく見えます。std::stringstream私が忘れてしまったことについて自明でないことがない限り。

于 2011-04-22T02:25:48.983 に答える