pthread导致的内存泄漏

时间:2018-07-31 16:26:08

标签: c++ memory pthreads

我正在用C ++开发一个项目,并且正在使用pthread。通过使用任务管理器,我可以注意到我的应用程序存在内存泄漏。

using namespace std;
int main()
{
        while(true){
            try{
                Foo * foo = new Foo(args ...);
                pthread_create(0,NULL,&Foo::doSomthing,NULL);
                pthread_join(0 ,NULL);
                delete foo;
            }catch (const std::bad_alloc&) {
              throw "";
            }
            Sleep(10);
            system("cls");
}
    return 0;
}

但是如果我直接调用该函数,内存泄漏就消失了

using namespace std;
int main()
{
        while(true){
            try{
                Foo * foo = new Foo(args ...);
                foo->doSomthing();
                delete foo;
            }catch (const std::bad_alloc&) {
              throw "";           
            }
            Sleep(10);
            system("cls");
}
    return 0;
}

2 个答案:

答案 0 :(得分:1)

我已将示例简化为

#include <pthread.h>

void* doSomthing(void *)
{
    return NULL;
}

int main()
{
    while (true)
    {
        pthread_create(0, NULL, doSomthing, NULL);
        pthread_join(0, NULL);
    }
    return 0;
}

用户代码中没有内存分配。该程序仍然泄漏。

pthread_create需要指向pthread_t的指针作为第一个参数。该指针将用作不透明的pthread句柄,并根据pthread_create的内部实现进行初始化。我们不知道这里发生了什么。我们不需要知道。坦白说,我们不想知道,因为这类信息破坏了抽象性,从而破坏了可移植性。

发问者的代码调用pthread_create为0。0将被视为NULL,这意味着pthread_create将在NULL指针上进行操作。这是经典的Undefined Behaviour。不要这样在Windows(带有g ++ 4.8的MinGW)上,这似乎导致线程运行,pthread_join失败(始终检查返回值!)以及大量内存泄漏。在Linux中,这似乎是立即致命的。

#include <pthread.h>
#include <iostream>

void* doSomthing(void *)
{
    return NULL;
}

int main()
{
    while (true)
    {
        pthread_t threadhandle;
        if (!pthread_create(&threadhandle, NULL, doSomthing, NULL))
        {
            if (pthread_join(threadhandle, NULL))
            {
                std::cerr << "Join fail\n";
            }
        }
        else
        {
            std::cerr << "Create fail\n";
        }
    }
    return 0;
}

提供指向有效线程句柄的指针不会泄漏。检查错误并报告错误有助于您调试和管理意外的故障。第二种方法应该适合您。

答案 1 :(得分:0)

您正在将0作为第一个参数传递给public class FirstMiddleware { private readonly RequestDelegate _next; public FirstMiddleware(RequestDelegate next) { _next = next; } public async Task InvokeAsync(HttpContext context) { await context.Response.WriteAsync($"This is { GetType().Name }"); //decide whether to invoke line below based on your business logic //await _next(context); bool isValid = userRegisterRequest.Validate(isJson: true, isThrowHttpError: true); //change userRegisterRequest.Validate to reutrn whether the model is valid if(!isValid) { await context.Response.WriteAsync($"Model is not valid"); } else { await _next(context); } } } ,因此您永远不会加入所创建的线程。这是您要泄漏内存的地方。

您需要加入创建的线程:

pthread_join()