簡體   English   中英

如何防止valgrind將靜態變量報告為泄漏?

[英]How can I prevent valgrind from reporting static variables as leaks?

有時,我會使用靜態變量僅在實際調用函數時才進行昂貴的初始化,並避免初始化每個調用。 例如...

#include <glib.h>
#include <stdbool.h>

bool is_blank(char *line) {
    static GRegex *blank_line_re = NULL;

    if( !blank_line_re ) {
        blank_line_re = g_regex_new(
            "^ \\s* $",
            G_REGEX_OPTIMIZE | G_REGEX_EXTENDED,
            0,
            NULL
        );
    }

    return g_regex_match(blank_line_re, line, 0, NULL);
}

不幸的是,valgrind會將其報告為內存泄漏。 我不認為靜態變量是內存泄漏。

如何防止valgrind將靜態變量報告為內存泄漏,而不必對每個變量進行特殊的抑制?

或者,C中是否有更好的模式來避免重新初始化?

Glib要求您調用g_regex_unref(GRegex *); 一旦完成了正則表達式。 因此,在程序完成之前,需要某種機制來進行此調用。

您可能有一個全局列表,在其中存儲了regex指針以最終取消對它們的引用,可以使GRegex *指針成為全局指針,您可以在其中最終使用它刪除對象,也可以重構以使指針返回一個單獨的函數,可以用來取消引用。

GRegex * my_blank_reg()
{
  static GRegex *blank_line_re = NULL;
  if (!blank_line_re) 
  {
    blank_line_re = g_regex_new(
      "^ \\s* $", G_REGEX_OPTIMIZE | G_REGEX_EXTENDED,  
      0, NULL);
  }
  return blank_line_re;
}

bool is_blank(char *line) 
{
  return g_regex_match(my_blank_reg(), line, 0, NULL);
}

void free_static()
{
  g_regex_unref(my_blank_reg());
}

int main()
{
  // do stuff with is_blank()

  free_static();
  return 0;
}

最簡單的方法是在全局或文件范圍內定義此類變量,然后在atexit處理程序中對其進行清理。

struct s *s1 = NULL;
struct s *s2 = NULL;

void free_global(void)
{
    free(s1);
    free(s2);
}

...
void f1(void)
{
    s1 = malloc(sizeof(struct s));
}

void f2(void)
{
    s2 = malloc(sizeof(struct s));
}

...

int main(void)
{
    atexit(free_global);
    ...
    f1();
    ...
    f2();
    ...
}

如果您真的想花哨的話,可以有一個void *的全局數組,該數組保留所有靜態/全局分配的副本,以便以后可以釋放它們,並制作一個函數,該函數采用新分配的指針並將其添加到列表中。

您的指針是靜態的,但是隨后您可以通過調用g_regex_new()使其指向已分配的緩沖區,並且必須釋放緩沖區。

valgrind具有“禁止文件”功能。 這是一個配置文件,它指示valgrind應忽略某些可能因泄漏而報告的內存分配。

在這種情況下,您應該使用適當的指令指定is_blank ()函數的內存分配,而不是is_blank()本身調用的任何其他函數的內存分配,也許應該忽略。

您將在valgrind的文檔中找到有關禁止文件的更多信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM