问题描述
我具有通过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;
}
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 ++代码很少需要new
或delete
任何东西,而在现代,干净的C ++代码中很少见到,它使用std::string
之类的对象和各种容器来正确处理所有内存分配和释放。避免与内存分配有关的错误的最简单方法是自己不做,而让C ++库为您管理内存。