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带有一点数据验证的略带 gimped 的包装器. 特别是,您没有以正确的方式强制执行Example呼叫用户。openclose

这不会打扰 valgrind,因为它是一个非常不同的工具。Valgrind 在你的程序运行时监视你的程序,以确保它不会发生任何愚蠢的事情,比如泄漏内存或内核资源,而这大概不会。PS 正在做某种静态分析,看看你是否有可能泄漏资源,在这种情况下你做到了(即使你没有继续实际利用这种可能性)。

我会重写这个类,使其更加 C++。特别是open_file()应该是构造函数,而不是可以随时调用的方法。close_file()应该等效地是析构函数,而不仅仅是一些随机方法。这应该让 Parallel Studio 满意,内核资源不能(通常)被泄露,除非对象本身被泄露(它可能会捕捉到其他地方的可能性,但无论如何,如果整个对象被泄露,它不是你的类的过错)。

不确定 PS 对内存泄漏的抱怨是什么;那条线对我来说很好。std::stringstream除非我忘记了一些不明显的事情。

于 2011-04-22T02:25:48.983 回答