0

我正在经历并尝试修复的一个应用程序中出现内存泄漏问题。我怀疑的问题之一是我使用 BNFC 将文件中的行解析为命令:

void LineStreamScriptProvider::populateQueue()
{
    if(shouldPopulate())
    {
        TasScript::ShowAbsyn shower;
        std::string line;
        while(queueSize() < 30 && !stream.eof())
        {
            std::getline(stream, line);
            const char* lineCStr = line.c_str();
            TasScript::Program* lineCmds = TasScript::pProgram(lineCStr);
            TasScript::P* asLeaf = static_cast<TasScript::P*>(lineCmds);
            TasScript::ListCommand* cList = asLeaf->listcommand_;
            for_each(cList->begin(), cList->end(), [this, shower](TasScript::Command* cmd) {
                // log_to_sd_out("Parsed command %s\n", shower->show(cmd));
                std::shared_ptr<TasScript::Command> cmdShared(cmd);
                pushToQueue(cmdShared);
            });
        }
        if(stream.eof())
        {
            afterEOF();
        }
    }
}

以供参考:

class P : public Program
{
public:
  ListCommand *listcommand_;
// ...
class ListCommand : public Visitable, public std::vector<Command*>
{
// ...

BNFC 用这些指针构造它们,new然后返回指针。delete lineCmds不删除 持有的值是否安全cmdShared

4

1 回答 1

1

抱歉,我不知道 BNFC,它会为您创建原始指针。

在不删除 cmdShared 持有的值的情况下删除 lineCmds 是否安全?

如果您从原始指针创建共享指针,则共享指针将拥有该资源的所有权。共享指针将维护该资源的引用计数,直到它降至零,即当该资源的所有共享指针超出范围时,它将尝试销毁该资源。

在这里,您正在创建一个共享指针并将其传递给队列:

std::shared_ptr<TasScript::Command> cmdShared(cmd);
pushToQueue(cmdShared);

共享指针将为您处理内存管理。所以不需要显式调用delete命令向量。一旦所有类型的共享指针std::shared_ptr<TasScript::Command>都被销毁,资源也会被销毁。

所以不,在这种情况下删除指针向量是不安全的。


另一个更简单的解决方案是复制一份TasScript::Command

TasScript::Command cmdCopy(*cmd);

然后更改pushToQueue()为接受const TasScript::Command&,而不是共享指针。然后你不必担心指针被破坏,因为你有一个值的副本。

看起来在您的 while 循环中您正在泄漏内存。您不必删除lineCmdsandcList吗?

于 2020-03-16T22:39:28.770 回答