在数组中使用 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;
你的内存泄漏了。此 new
ed char
缓冲区未在任何地方得到 delete
d。
此外,char
缓冲区太小,这也会导致内存损坏。除非已修复,否则随着您继续重复开发此代码 and/or 运行 此代码,此程序将开始在随机、无关的地方随机崩溃。
我没有看到通过将 std::string
的内容复制到单独的 char
缓冲区(太小)中的所有这些复杂而精细的步骤实际完成的任何事情,然后泄漏它。看起来这个 const char *
的唯一用途是构建一个完全独立的 std::string
,此时内存泄漏。
最简单的解决方法是完全摆脱所有这些。这应该只是 return
原来的 std::string
。一般来说,现代 C++ 代码很少需要 new
或 delete
任何东西,这在使用 std::string
和各种容器正确处理所有内存的现代、干净的 C++ 代码中很少见分配和解除分配。避免与内存分配相关的错误的最简单方法就是不自己动手,让 C++ 库为您管理内存。
我有这个功能,它通过 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;
你的内存泄漏了。此 new
ed char
缓冲区未在任何地方得到 delete
d。
此外,char
缓冲区太小,这也会导致内存损坏。除非已修复,否则随着您继续重复开发此代码 and/or 运行 此代码,此程序将开始在随机、无关的地方随机崩溃。
我没有看到通过将 std::string
的内容复制到单独的 char
缓冲区(太小)中的所有这些复杂而精细的步骤实际完成的任何事情,然后泄漏它。看起来这个 const char *
的唯一用途是构建一个完全独立的 std::string
,此时内存泄漏。
最简单的解决方法是完全摆脱所有这些。这应该只是 return
原来的 std::string
。一般来说,现代 C++ 代码很少需要 new
或 delete
任何东西,这在使用 std::string
和各种容器正确处理所有内存的现代、干净的 C++ 代码中很少见分配和解除分配。避免与内存分配相关的错误的最简单方法就是不自己动手,让 C++ 库为您管理内存。