簡體   English   中英

在子進程中使用std :: string時出現C ++內存泄漏

[英]C++ memory leak while using std::string in child process

我對這段代碼有問題,valgrind檢測到std :: basic_string中的內存泄漏,我不知道我做錯了什么。 只有在子進程中使用std :: string時才會泄漏。 你能告訴我,問題在哪里嗎? 我之前從未在C ++中使用過fork(),因此我沒有太多的經驗。

#include <iostream>
#include <string>
#include <cerrno>
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <sys/wait.h>

int main(int argc, char *argv[])
{
    pid_t childPid = fork();
    if (childPid == -1)
    {
      perror("fork");
      return EXIT_FAILURE;
    }
    else if (childPid == 0)
    {
      std::cout << "Child PID: " << getpid() << std::endl;
      std::string str("something");      //valgrind detects mem leak here
      _Exit(EXIT_SUCCESS);
    }
    else
    {
      //std::string str("something");    //but not here
    }

    waitpid(-1, 0, 0);
  return EXIT_SUCCESS;
}

_Exit不會運行任何析構函數或atexit函數,它只是立即結束。

顯然,這通過RAII打了一個巨大的洞,所以不要這樣做。


在保持相同的退出策略的同時實現Do not Do的一種方法可能是:

template <typename Func, typename... Args>
int wrap_cpp_code(Func&& func, Args&&.. args)
{
    try
    {
        return std::forward<Func>(func)(std::forward<Args>(args)...);
    }
    catch (...)
    {
        return EXIT_FAILURE;
    }
}

在其范圍內的所有析構函數運行之前,不會咳出返回值,給出:

int child_main(int argc, char *argv[])
{
    std::cout << "Child PID: " << getpid() << std::endl;
    std::string str("something");

    return EXIT_SUCCESS;
}

int main(int argc, char *argv[])
{
    pid_t childPid = fork();
    if (childPid == -1)
    {
      perror("fork");

      return EXIT_FAILURE;
    }
    else if (childPid == 0)
    {
      int ret = wrap_cpp_code(child_main, argc, argv);
      _Exit(ret);
    }
    else
    {
      /*
      int ret = wrap_cpp_code(xyz, argc, argv);
      */
    }

    waitpid(-1, 0, 0);

    return EXIT_SUCCESS;
}

但這仍然無法解釋atexit函數或全局析構函數。 所以仍然避免這樣做。

暫無
暫無

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

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