gcc/linux:CppuTest 使用静态向量显示内存泄漏,误报?

Posted

技术标签:

【中文标题】gcc/linux:CppuTest 使用静态向量显示内存泄漏,误报?【英文标题】:gcc/linux: CppuTest shows memory leak using static vectors, false positive? 【发布时间】:2012-06-04 10:52:48 【问题描述】:

在 xxxx.h 文件中:

struct dn_instance_pair

    std::string theDn;
    int theInstance;
;
typedef struct dn_instance_pair t_dn_inst_pair;

struct table_rowid_type

    char theTable[101];
    sqlite3_int64 theRowid;
    int operation;
;

// static class members
static vector<t_dn_inst_pair> dninstList;
static vector<t_table_rowid_type> tablerowidList;

在 xxxx.cpp 中

// declaration of vectors.
// Included to this post only for completeness.
vector<t_dn_inst_pair> xxxx::dninstList;
vector<t_table_rowid_type> xxxx::tablerowidList;

这些向量在静态回调函数中处理,所以它们也必须是静态的。

在 cpputest 中,当尝试在任一向量中添加内容时,会发生故障:

Leak size: 8 Allocated at: <unknown> and line: 0. Type: "new" Content: "<\ufffdP@"

添加到向量中的东西是自动变量,它发生在普通函数中:

t_dn_inst_pair thePair;
thePair.theDn = updated_dn;
thePair.theInstance = updated_instance;

向量在测试用例结束时被清除:

xxxx::yyyy()->dninstList.clear();

(yyyy() 返回一个指向单例 xxxx 对象的指针)

页面http://blog.objectmentor.com/articles/2010/02/04/cpputest-recent-experiences 讨论了相同类型的内存泄漏:

“这是误报。这是一次性分配和 C++ 内存分配和静态初始化的副作用。”

所以我的问题是: 这种失败真的是误报吗?

br 埃斯科

【问题讨论】:

【参考方案1】:

你检查过 valgrind 吗?它将区分“肯定丢失”的泄漏内存和“仍然可以访问”的内存。如果它是误报,它应该仍然可以访问(通过向量中的指针。)

请记住,vector::clear() 只是销毁元素,它不会释放任何内存,因此capacity() 将保持不变。

您可以使用交换技巧来强制向量释放其内存:

vector<t_dn_inst_pair>().swap(xxxx::yyyy()->dninstList);

这将创建一个临时(空)向量并将其与您的向量交换,因此您的向量的元素和分配的内存将被转移到临时,然后在语句结束时销毁。

附:单例很糟糕,不要使用它们,但是如果它是静态成员,为什么要以 yyyy()-&gt;dninstList 访问向量(即使用 operator-&gt;)?你可以说 xxxx::dninstList 或将其设为非静态成员并通过单例对象访问它(但不要忘记单例很糟糕。)

【讨论】:

您好乔纳森,感谢您的回答。是的,我与 Valgrind 核对过;没有内存泄漏。 valgrind --tool=memcheck --leak-check=full --show-reachable=yes ./executable。我将添加用于解除分配的交换技巧。并将尝试将向量更改为非静态并通过单例访问它们(尽管它很烂;)。 br Esko 我相信它实际上是因为破坏顺序而出现的。 IE。只有在 CppUTest 已经报告了泄漏之后,内存才真正被释放。原因是静态对象仅在main() 函数返回后在全局销毁期间被销毁(并释放其内存),但 CppUTest 可能会在测试驱动程序结束时报告泄漏,这意味着仍在main() 中。这可以解释为什么 Valgrind 即使使用 --show-reachable=yes 也不显示它们。 嗨乔纳森,非静态的工作就像一个魅力。我也做了交换。谢谢 !也感谢 Jan 的解释 这也适用于unique_ptr,交换解决方案也解决了我的问题!谢谢!

以上是关于gcc/linux:CppuTest 使用静态向量显示内存泄漏,误报?的主要内容,如果未能解决你的问题,请参考以下文章

使用 MinGw 编译最新版本的 CppUTest (3.7),缺少 pthreads

CppUTest:如何将更多数据传递给特定的模拟调用?

测试驱动开发 001:VSCode + CMake + CppUTest 环境搭建

测试驱动的嵌入式开发 001:VSCode + CMake + CppUTest 环境搭建

测试驱动的嵌入式开发 001:VSCode + CMake + CppUTest 环境搭建

C++ 使用向量作为类实例的静态容器