首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >也许是某个资源没有发布?是什么导致了这种情况?

也许是某个资源没有发布?是什么导致了这种情况?
EN

Stack Overflow用户
提问于 2010-01-26 12:55:12
回答 3查看 313关注 0票数 2

我正在做一个项目,我到了一个点,弹出了以下堆栈跟踪:

代码语言:javascript
复制
#0  0x0017c30c in _IO_flush_all_lockp () from /lib/libc.so.6
#1  0x0017d030 in _IO_cleanup () from /lib/libc.so.6
#2  0x0013e042 in exit () from /lib/libc.so.6
#3  0x00126bbe in __libc_start_main () from /lib/libc.so.6
#4  0x08049d11 in _start ()

(删除了代码,因为内存泄漏已得到解决。当然,还有其他人。不过,我会更努力地追踪他们,然后再把他们贴在这里。:)最初的问题可能与内存泄漏无关。)

首先,从最初的堆栈跟踪开始,我看的方向是否正确?在处理内存问题时,我从未见过这种情况。有什么想法吗?

编辑:有人说这是因为visual_mem_new0。该函数只是分配内存。它对plugin->作者一无所知。

编辑: Duh。strdup之前的memcopy会填充内存。

Edit:好的,这样就消除了一个内存泄漏。我不相信最初的堆栈跟踪完全是关于内存泄漏的--例如,它仍然存在。我相信它是在尝试释放一些资源。这个程序的一部分使用了很多编译过的汇编(JIT编译器),它在文件描述符上使用mmap的内存作为缓冲区。我要关闭这份文件。我需要对内存映射做些什么吗?

不过,我会继续尝试清除这些内存泄漏。我最近做了一些与特定插件相关的事情。只有当我运行这个插件时,程序才会挂起,这个插件使用了我提到的内存映射。我不确定会是什么。我做了一些小改动。最初,我怀疑是一个共享指针,我跟踪它的引用。它使用的系统在整个libvisual中都是相同的,并且没有出现内存泄漏。无论如何,我希望有人对此有一些线索。我想不出还有什么可补充的。

编辑:好的,在修改历史的帮助下找到了它。下面的代码有什么问题?我能不能像那样把输出复制到自己身上?

代码语言:javascript
复制
static inline int dump_stack(AvsCompilerContext *ctx)
{
    AvsCompilerArgument *pa;
    char output[2048];

    snprintf(output, 2047, "\ncompiler: stackdump: Stack dump\n");
    for (pa=(AvsCompilerArgument *)ctx->stack->base; pa < (AvsCompilerArgument *)ctx->stack->pointer; pa++) {
        snprintf(stderr, 2047, "%scompiler: stackdump: [%2d] = ", output, (pa - (AvsCompilerArgument *)ctx->stack->base));
        switch (pa->type) {
            case AvsCompilerArgumentInvalid:
                snprintf(output, 2047, "%sinvalid", output);
                break;

            case AvsCompilerArgumentConstant:
                snprintf(output, 2047, "%s%.2f", output, pa->value.constant);
                break;

            case AvsCompilerArgumentIdentifier:
                snprintf(output, 2047, "%s", pa->value.identifier);
                break;

            case AvsCompilerArgumentMarker: {
                char *markers[] = { "invalid", "function", "argument", NULL };
                snprintf(output, 2047, "%s--- %s marker ---", output, markers[pa->value.marker]);
                break;
            }

            case AvsCompilerArgumentPrivate:
                snprintf(output, 2047, "%sprivate", output);
                break;

        }
        snprintf(output, 2047, "\n");
    }

    avs_debug(print(output));
    return VISUAL_OK;
}

宏avs_debug什么也不做。我把它的内容注释掉了。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-01-26 13:27:32

由于您正在执行strdup(),因此应该使用free()释放这些值。我不确定visual_mem_free()是否会调用free()。如果您尝试使用free()而不是visual_mem_free(),那么valgrind错误会消失吗?

编辑:你的snprintf()调用是错误的:

代码语言:javascript
复制
snprintf(output, 2047, "%sinvalid", output);

snprintf()是C99,标准是(7.19.6.5p2):

如果在重叠的对象之间进行复制,则行为未定义。

确切的语句也适用于C89中的sprintf()

解决问题的最简单方法是:

代码语言:javascript
复制
char init[] = "\ncompiler: stackdump: Stack dump\n";
size_t init_len = sizeof init - 1;
snprintf(output, 2047, "\ncompiler: stackdump: Stack dump\n");

然后是:

代码语言:javascript
复制
snprintf(output+init_len, sizeof output - init_len, "%.2f", pa->value.constant);

(请检查上面的off-by-one错误。)

另外,我不确定为什么要在其中一个调用中使用stderr作为第一个参数来调用snprintf()。您是否在编译代码时启用了警告?

票数 1
EN

Stack Overflow用户

发布于 2010-01-26 13:09:30

visual_plugin_info_new调用分配内存的visual_mem_new0,您需要在visual_plugin_info_copy中分配插槽之前释放它们。

票数 3
EN

Stack Overflow用户

发布于 2010-01-26 16:35:06

在你发布的最后一段代码中可能至少有两个问题(问题的编辑让事情变得非常混乱,因为你现在试图处理的是什么问题):

  1. ,你有一行启动snprintf(stderr, 2047, etc...)的代码。这几乎可以肯定是一个复制-粘贴错误,因为它不应该编译。您可能打算在snprintf()调用中使用fprintf().
  2. You,而不能同时使用目标缓冲区作为源。该标准说,“如果在重叠的对象之间进行复制,则行为是未定义的”。如果你仔细考虑一下,你可能会意识到,如果不首先将缓冲区复制到其他地方,它在一般情况下是不能工作的。尝试在vsnprintf() (可能名为snprintfcat())周围创建一个包装器,将格式化的字符串连接到目标缓冲区。要做到这一点并不太难,尽管它需要使用varargs,这可能有点棘手--但只有一点点。

下面是一个完全未经测试的snprintfcat()函数-它可以编译,但如果超过这个范围,风险自负:

代码语言:javascript
复制
int snprintfcat( char* dest, size_t siz, char const* fmt, ...)
{
    size_t len = strnlen( dest, siz);
    size_t remainder = 0;
    int result;

    va_list ap;

    if (len < siz) {
        remainder = siz - len;
    }

    va_start( ap, fmt);
    result = vsnprintf( dest+siz-remainder, remainder, fmt, ap);
    va_end( ap);

    return result + siz - remainder;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2137588

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档