泄漏和地址有什么区别?

das*_*fex 2 c++ address-sanitizer

我在我的项目中使用-fsanitize=leak-fsanitize=address。我认为泄漏发现内存泄漏(不删除内存)和地址发现拧内存访问。但是地址也说明了未删除的内存。那么,-fsanitize=leak需要出于什么目的呢?

use*_*677 5

解释

地址清理器会做一些额外的事情,比如检查你是否正在写入越界的内存。泄漏消毒器只会检查您是否忘记释放内存。

文档

您可以在 gcc程序检测选项页面上阅读这些内容。

-fsanitize=address

启用 AddressSanitizer,这是一种快速内存错误检测器。内存访问指令用于检测越界和释放后使用错误。该选项启用-fsanitize-address-use-after-scope. 有关更多详细信息,请参阅https://github.com/google/sanitizers/wiki/AddressSanitizer。可以使用ASAN_OPTIONS环境变量影响运行时行为。设置为 时help=1,可用选项将在检测程序启动时显示。有关支持的选项列表,请参阅https://github.com/google/sanitizers/wiki/AddressSanitizerFlags#run-time-flags。该选项不能与-fsanitize=thread.

-fsanitize=leak

启用内存泄漏检测器 LeakSanitizer。此选项仅对链接可执行文件很重要,并且可执行文件链接到覆盖 malloc 和其他分配器函数的库。有关更多详细信息,请参阅https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer。可以使用LSAN_OPTIONS环境变量影响运行时行为。该选项不能与-fsanitize=thread.

-fsanitize-address-use-after-scope

启用局部变量清理以检测作用域后使用错误。该选项设置-fstack-reusenone

-fstack-reuse=reuse-level

可以在代码生成选项页面上找到文档。

此选项控制用户声明的本地/自动变量和编译器生成的临时变量的堆栈空间重用。Reuse_level 可以是“all”、“named_vars”或“none”。'all' 为所有局部变量和临时变量启用堆栈重用,'named_vars' 仅启用用户定义的具有名称的局部变量的重用,'none' 完全禁用堆栈重用。默认值为“全部”。当程序将范围局部变量或编译器生成的临时变量的生命周期扩展到语言定义的端点之外时,需要该选项。当变量的生命周期结束时,如果变量存在于内存中,优化编译器可以自由地将其堆栈空间与其他临时变量或作用域局部变量重用,这些变量的生命范围不与其重叠。

例如,

int *p;
{
  int local1;

  p = &local1;
  local1 = 10;
  ....
}

{
  int local2;
  local2 = 20;
  ....
}

if (*p == 10) // out of scope use of local1
{

}
Run Code Online (Sandbox Code Playgroud)

另一个例子:

struct A {
  A(int k) : i(k), j(k) { }
  int i;
  int j;
};

A *ap;

void foo(const A& ar) {
  ap = &ar;
}

void bar() {
  foo(A(10)); // temp object's lifetime ends when foo returns

  {
     A a(20);
     ....
  }

  ap->i += 10; // ap references out of scope temp whose space
               // is reused with a. What is the value of ap->i?
}
Run Code Online (Sandbox Code Playgroud)

C++ 标准很好地定义了编译器生成的临时文件的生命周期。当临时变量的生命周期结束时,如果临时变量存在于内存中,优化编译器可以自由地将其堆栈空间与其他临时变量或有效范围不与其重叠的局部变量重用。然而,一些遗留代码依赖于不重用临时堆栈空间的旧编译器的行为,激进的堆栈重用会导致运行时错误。此选项用于控制临时堆栈重用优化。


Nic*_*las 3

为了找到内存泄漏,该工具需要查看分配内存的所有位置,标记它们,跟踪它们何时被删除,并查看是否有任何在程序结束时未删除。

为了找到内存写入访问冲突,该工具需要(除其他外)查看分配内存的所有位置,标记它们,并跟踪它们何时被删除。这是必要的,因为它会使分配更大,这样它就可以在它们周围放置防护装置来检测您何时进行疯狂写入。

因此,基本上跟踪内存泄漏所需的 90% 的信息都可用于解决清理程序。所以它也可能会跟踪这些。

您不只是为了查找内存泄漏而使用地址清理程序的原因是它可以执行很多其他操作