共享指针后,删除指针向量的父对象是否安全?
Safe to delete parent of vector of pointers when those pointers have been shared?
我正在尝试修复的其中一个应用程序出现内存泄漏问题。我怀疑的问题点之一是我使用 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
然后 returns 指针构造这些。在不删除 cmdShared
持有的值的情况下 delete lineCmds
是否安全?
抱歉,我不知道 BNFC,它会为您创建原始指针。
Is it safe to delete lineCmds without deleting the value held by
cmdShared?
如果您从原始指针创建共享指针,共享指针将获得该资源的所有权。共享指针将维护该资源的引用计数,直到它降为零,即当该资源的所有共享指针超出范围时,此时它将尝试销毁该资源。
这里您正在创建一个共享指针并将其传递给队列:
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 循环似乎在泄漏内存。 lineCmds
和 cList
不是必须删除吗?
我正在尝试修复的其中一个应用程序出现内存泄漏问题。我怀疑的问题点之一是我使用 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
然后 returns 指针构造这些。在不删除 cmdShared
持有的值的情况下 delete lineCmds
是否安全?
抱歉,我不知道 BNFC,它会为您创建原始指针。
Is it safe to delete lineCmds without deleting the value held by cmdShared?
如果您从原始指针创建共享指针,共享指针将获得该资源的所有权。共享指针将维护该资源的引用计数,直到它降为零,即当该资源的所有共享指针超出范围时,此时它将尝试销毁该资源。
这里您正在创建一个共享指针并将其传递给队列:
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 循环似乎在泄漏内存。 lineCmds
和 cList
不是必须删除吗?