提问人:Hikaru 提问时间:10/5/2023 最后编辑:Hikaru 更新时间:10/6/2023 访问量:150
循环中的 C++ std::unique_ptr - 内存泄漏
c++ std::unique_ptr in a loop - memory leaks
问:
unique_ptr在这个循环中是否正确使用?
每次此 while 循环结束时,整体堆大小都会略有增加。当我使用 Visual Studio 的调试工具调查代码时,似乎没有释放unique_ptr对象“task”,导致内存泄漏。
我以为unique_ptr记忆会在大括号结束后释放,在这种情况下,是每个循环的结束或 try-catch 的结束大括号。是不是有什么误会?
我的环境:VisualStudio2019、MSVC、C++17
更新(2023/10/6)
- 我更新了代码如下。
- 试图进行最低限度的复制,但由于某种原因我无法做到。因此,此代码可以正常工作,而不会发生内存泄漏。唯一的尊重是每个类的头文件和类名。我很困惑。
- 这是调试工具的屏幕截图。我想知道为什么这个_container_proxy[]、TaskFactory[] 和 TaskImplA[] 不断堆积。
#include <iostream>
#include <future>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
#include <ws2tcpip.h>
class MessageTask {
public:
MessageTask() {};
MessageTask(char*& message) {};
virtual ~MessageTask() {};
void execute() {
decide_task();
do_task();
}
virtual void decide_task() = 0;
virtual void do_task() = 0;
};
class TaskImpl : public MessageTask{
private:
char* message;
public:
TaskImpl() {};
TaskImpl(char*& message) { this->message = message; };
~TaskImpl() {};
void decide_task() { std::cout << message << std::endl; return; };
void do_task() { return; };
};
class TaskFactory {
public:
TaskFactory() {};
~TaskFactory() {};
std::unique_ptr<MessageTask> create_message_task(char*& message, int& sender) {
if (sender == 2000) {
return std::make_unique<TaskImpl>(message);
}
return nullptr;
};
};
class UdpComm {
private:
SOCKET m_socket;
struct sockaddr_in m_address;
WSADATA m_wsadata;
public:
UdpComm() {};
~UdpComm() {};
struct sockaddr_in m_address_send_from;
void initialize_receiver() {
WSACleanup();
int startup_result = WSAStartup(MAKEWORD(2, 0), &this->m_wsadata);
this->m_socket = socket(AF_INET, SOCK_DGRAM, 0);
this->m_address.sin_family = AF_INET;
this->m_address.sin_port = htons(5001);
this->m_address.sin_addr.S_un.S_addr = INADDR_ANY;
int wsa_result = bind(this->m_socket, (struct sockaddr*)&this->m_address, sizeof(this->m_address));
};
int receive_sync(char* buffer_ptr, const size_t buffer_size, size_t& rx_size)
{
int sockaddr_in_size = sizeof(this->m_address_send_from);
int receive_result = recvfrom(this->m_socket, (char*)buffer_ptr, (int)buffer_size, 0, (struct sockaddr*)&m_address_send_from, &sockaddr_in_size);
rx_size = (size_t)receive_result;
return 0;
}
};
class Receiver {
public:
int udp_receive(UdpComm& uc_rcv) {
while (true)
{
try
{
char buffer[1024];
char* buffer_ptr = buffer;
size_t buffer_size = sizeof(buffer);
size_t rx_size = 0;
uc_rcv.receive_sync(buffer_ptr, buffer_size, rx_size);
int port = ntohs(uc_rcv.m_address_send_from.sin_port);
auto factory = std::make_unique<TaskFactory>();
auto task = factory->create_message_task(buffer_ptr, port);
task->execute();
}
catch (const std::exception& ex)
{
std::cerr << "[ERROR] " << ex.what() << std::endl;
}
}
}
};
int main() {
auto uc_rcv = std::make_unique<UdpComm>();
uc_rcv->initialize_receiver();
Receiver receiver;
receiver.udp_receive(*uc_rcv);
}
我使用 Visual Studio 2019 的调试工具进行了调查,它显示堆大小增加了。另外,我在 task->execute() 中注释掉了以下过程,但仍然发生了内存泄漏。
答: 暂无答案
评论
create_message_task
execute
static
create_message_task()
static
udp_receive