QT删除可与Valgrind一起使用,但不能正常执行
Qt delete works with Valgrind but not normal execution
我正在使用qtCreator和valgrind在QT程序中检查内存泄漏。我正在删除在灾难中的Qhash中的一些条目:
QHash<QString, QVariant*> m_Hash;
/**
* @brief
* Destruct a Foo Class instance
*/
Foo ::~Foo ()
{
// Do Cleanup here
// Delete hash leftovers
foreach( QString key, m_Hash.keys() )
{
qDebug() << "Deleting an entry..";
// Delete the hash item
delete m_Hash.take(key);
}
}
如果我使用Valgrind进行调试,则此代码很好,并在称为destructor时删除内容:
>> Deleting an entry..
>> Deleting an entry..
如果我在qtCreator中使用GDB启动,则从qtCreator启动,或者只需从命令行运行我的qt应用程序,我会得到分割错误!
Signal name :
SIGSEGV
Signal meaning :
Segmentation fault
如果我赞扬"删除"行,那么我可以使用任何方法运行我的应用程序,但是我确实泄漏了内存。
什么给?Valgrind是否引入了某种延迟,使我的驱动器可以工作?我该如何解决?
hyde的答案正确;但是,清除特定哈希的最简单方法如下:
#include <QtAlgorithms>
Foo::~Foo()
{
qDeleteAll(m_Hash);
m_Hash.clear();
}
请注意,如果哈希表的键是指针(例如QHash<QString*, QVariant>
)。
您无法通过foreach修改您的容器。改用迭代器。使用方法iterator QHash::erase ( iterator pos )
正确代码:
QMap<QString, QVariant* >::iterator it = m_Hash.begin();
// auto it = m_Hash.begin(); // in C++11
while (it != m_Hash.end()) {
delete it.value();
it = m_Hash.erase(it);
}
另外,您要存储QVariant指针而不是价值的任何特定原因?Qvariant通常适合保持值为价值,因为您存储在QVariant中的大多数数据是隐式共享的,或者很小。
文档没有明确提及它,但是您正在突变您正在迭代的容器。
foreach
的代码在这里。
查看代码,IT和您的代码基本上与您要编写的代码相同:
for (QHash::iterator it=m_Hash.begin(), end=m_Hash.end();
it!=end;
++it)
{
delete m_Hash.take(key);
}
但是,take
成员函数可能会触发现有迭代器的无效(it
和end
),因此您的迭代器可能已经悬挂,产生了未定义的行为。
可能的解决方案:*请勿在迭代时通过修改容器您的迭代器*确保it
在下一次迭代开始之前有效,并且不要存储end
-列表(此解决方案禁止使用foreach
)
也许foreach关键字存在问题。尝试更换:
foreach( QString key, m_Hash.keys() )
{
qDebug() << "Deleting an entry..";
delete m_Hash.take(key); // take changes the m_Hash object
}
with:
for (QHash<QString, QVariant*>::iterator it = m_Hash.begin();
it != m_Hash.end(); ++it)
{
qDebug() << "Deleting an entry..";
delete it.value(); // we delete only what it.value() points to, but the
// m_Hash object remains intact.
}
m_Hash.clear();
这样,在您迭代它时,哈希表保持不变。foreach宏可能会扩展到您"从脚下删除凸面"的结构。那是宏可能会产生一个迭代器,它成为无效或"悬空"作为调用的副作用
m_Hash.take(key);
- 是否可以将函数导入命名空间,但不能导出它?
- std::unique_ptr 在 GCC 中工作,但不能在 Visual Studio 中编译
- 声明C++具有动态大小的数组类型在 Linux 中工作正常,但不能在 Windows 中工作
- 为什么我可以隐式地将字符*转换为常量字符*,但不能将无符号字符*
- std::chrono::d uration 可以按秒初始化,但不能按毫秒初始化?
- Python/C++:可以导入犰狳(arma::)但不能导入子程序arma::arma_rng::randn
- 为什么我可以从C++文件中读取 int 值,但不能浮点?
- C++程序在将 int 与 cin 一起使用时有效,但不能使用字符串
- SqLite c++,可以创建数据库,但不能将 anthing 插入到表中
- std::remove() 按预期处理文字,但不能与取消引用的迭代器一起工作
- 16 位系统中的程序如何访问大于 65535 的整数,但不能访问地址
- C++:返回本地对象,但不能正常工作
- 可以访问一个类中的播放器结构,但不能访问另一个类中的播放器结构
- 返回实例变量的c++方法可以访问变量中的数据,但不能更改它,但在编译时不会生成错误
- 用C++替换std::字符串中的一个子字符串,但不能全部替换
- 我可以在Windows(Visual C++)中读取bin文件,但不能在linux(GCC)上读取bin文件
- 我可以固定C 可执行文件,但不能共享库
- QT删除可与Valgrind一起使用,但不能正常执行
- C++中的简单代码正在编译,但不能在Linux中执行
- 链表析构函数与Valgrind一起执行,但不能单独执行