在数组中使用 ssh_channel_open_session 时内存泄漏

memory leak while using ssh_channel_open_session in an array

我有这个功能,它通过 ssh 通道执行命令:

std::string ssh::exec_ssh_command(const char* command)
{
    std::string receive = "";
    std::string err;
    int rc, nbytes;
    char buffer[2000];
    MyException errMsg;
    try {
        ssh_channel channel = ssh_channel_new(my_ssh_session);
        if (channel == NULL)
        {
            receive = "Channel allocation failed.";
            throw MyException(receive);
        }
        rc = ssh_channel_open_session(channel);
        if (rc != SSH_OK)
        {
            receive = "Opening session channel failed : ";
            receive += ssh_get_error(my_ssh_session);

            throw MyException(receive);
        }

        rc = ssh_channel_request_exec(channel, command);
        if (rc != SSH_OK) {
            receive = "Channel's request executing failed.";
            throw MyException(receive);
        }
        nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
        receive = buffer;
        if (nbytes > 0)
        {
            receive.erase(nbytes - 1, 2000);
        }
        else
        {
            receive = "Error in command: not found or wrong syntax";
            throw MyException(receive);
        }

        if (nbytes < 0)
        {
            receive = "Error in reading data from channel ";
            throw MyException(receive);
        }

        ssh_channel_free(channel);
    }
    catch (MyException& err)
    {
        ssh_channel_free(channel);

        throw err;

    }
    return receive;
}

我之前用这个函数来执行 运行 命令并得到一个输出。现在我想在循环中使用这个函数,如下所示:

Service monitoring::osFields()
{
    std::string num;
    int serviceNumbers, active, faild, loaded, not_found;
    serviceNumbers = getServiceNumbers();
    Service *services = new Service[serviceNumbers];

    std::string service_name_command;
    std::string service_load_state_commands;
    std::string service_active_state_commands;
    std::string service_sub_state_commands;
    try
    {
        num = sshObj->exec_ssh_command("systemctl list-units --state active | grep service | wc -l");
        active = std::stoi(num);
        for (int i = 0; i < active; i++)
        {
            service_name_command = "systemctl list-units --state active | grep service | sed -s -n " + std::to_string(i+1) + "p | awk '{print }'";
            services[i].name = sshObj->exec_ssh_command(service_name_command);

            service_load_state_commands = "systemctl list-units --state active | grep service | sed -s -n " + std::to_string(i+1) + "p | awk '{print }'";
            services[i].load = sshObj->exec_ssh_command(service_load_state_commands);

            service_active_state_commands = "systemctl list-units --state active | grep service | sed -s -n " + std::to_string(i + 1) + "p | awk '{print }'";
            services[i].active = sshObj->exec_ssh_command(service_active_state_commands);

            service_sub_state_commands = "systemctl list-units --state active | grep service | sed -s -n " + std::to_string(i + 1) + "p | awk '{print }'";
            services[i].sub = sshObj->exec_ssh_command(service_sub_state_commands);

        }
        
    }
    catch (MyException& err)
    {
        throw MyException("in function smc_getNICs ::" + string(err.what()));
    }
    return *services;
}

getServiceNumbers();是统计服务次数的函数。
这是 Service 结构:

struct Service {
    const char* name;
    const char* load;
    const char* active;
    const char* sub;
};

我有一个 connectSession 函数,它在 ssh class 的构造函数中被调用并建立一个 ssh 会话。每当我 运行 我的代码时,它都会在 i=43 中崩溃。它是关于 memory leak 并且大部分停止在 ssh_channel_open_session 函数中,但有时在 ssh_channel_request_exec 中停止。
编辑:
exec_ssh_comman 超载:


const char * ssh::exec_ssh_command(std::string command)
{
    const char* _retVal = NULL;

    _retVal = stringToConstChar(exec_ssh_command(command.c_str()));

    return _retVal;
}

stringToChar函数:

const char* stringToConstChar(string str)
{
    const char* command = new char[str.size()];
    strcpy((char*)command, str.c_str());
    const char* cm = command;
    return cm;
}
const char* command = new char[str.size()];
strcpy((char*)command, str.c_str());
const char* cm = command;
return cm;

你的内存泄漏了。此 newed char 缓冲区未在任何地方得到 deleted。

此外,char 缓冲区太小,这也会导致内存损坏。除非已修复,否则随着您继续重复开发此代码 and/or 运行 此代码,此程序将开始在随机、无关的地方随机崩溃。

我没有看到通过将 std::string 的内容复制到单独的 char 缓冲区(太小)中的所有这些复杂而精细的步骤实际完成的任何事情,然后泄漏它。看起来这个 const char * 的唯一用途是构建一个完全独立的 std::string,此时内存泄漏。

最简单的解决方法是完全摆脱所有这些。这应该只是 return 原来的 std::string。一般来说,现代 C++ 代码很少需要 newdelete 任何东西,这在使用 std::string 和各种容器正确处理所有内存的现代、干净的 C++ 代码中很少见分配和解除分配。避免与内存分配相关的错误的最简单方法就是不自己动手,让 C++ 库为您管理内存。