2013-03-27 51 views
3

我遇到了这段代码的问题,valgrind在std :: basic_string中检测到内存泄漏,我不知道我做错了什么。只有在子进程中使用std :: string时才会发生泄漏。你能告诉我,问题在哪里?我从来没有在C++中使用fork(),所以我没有太多的经验。在子进程中使用std :: string时C++内存泄漏

#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; 
} 
+3

而不是调用'_Exit'尝试像函数结束时那样返回。 – 2013-03-27 22:39:15

+3

_Exit是否阻止堆栈退出?这可能会阻止std :: string析构函数的运行。 – Ben 2013-03-27 22:40:49

回答

9

_Exit将不能运行任何析构函数或atexit功能,它只是立即结束。

很显然,这通过RAII打一个巨大的洞,所以不要这样做。落实不这样做,同时保持相同的退出策略可能是


方式一:

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; 
} 

但是,这仍然无法解释函数或全局析构函数。所以仍然避免这样做。