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

问题描述

我具有通过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 $1}'";
            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 $2}'";
            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 $3}'";
            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 $4}'";
            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类的构造函数调用并进行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;

有您的内存泄漏。 new版的char缓冲区在任何地方都没有delete d。

此外,char缓冲区太小,这也会导致内存损坏。除非已修复,否则当您继续重复开发和/或运行此代码时,该程序将在随机,不相关的地方随机崩溃。

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

最简单的解决方法是完全摆脱所有这些。这应该只是return原始的std::string。通常,现代C ++代码很少需要newdelete任何东西,而在现代,干净的C ++代码中很少见到,它使用std::string之类的对象和各种容器来正确处理所有内存分配和释放。避免与内存分配有关的错误的最简单方法是自己不做,而让C ++库为您管理内存。