2011-06-22 164 views
0
void ServerManager::addWork(SocketClient *clientSocket, vector<char> data){ 
    Work *work = new Work(clientSocket, data); 
    m_workHandler->addWork(work); 
} 

这里我创建了Work实例并将工作交给WorkHandler。我应该在哪里释放物体?

m_workHandler->addWork(work); 

此代码将工作插入到队列中。

这是我的服务器的一个组成部分,如果我在很长一段时间这个代码,然后错误的服务器崩溃说这样

what() std::bad_alloc 

我在网上看了看,它是显示有ISN的错误消息” t可用内存空间。所以我意识到在完成使用后我没有释放工作对象。

所以我想知道在哪里我应该释放工作对象。

void ServerManager::addWork(SocketClient *clientSocket, vector<char> data){ 
    Work *work = new Work(clientSocket, data); 
    m_workHandler->addWork(work); 
    delete work; 
} 

我可以这样做吗?如果我通过工作实例,那么它会增加引用计数?

void WorkHandler::workLoop(){ 
    printf("WorkHandler::workLoop, called\n"); 

    while(m_workHandlerRun){ 
     Work *work = getWork(); 
     char *pdata = work->getVPointer(); 

     unsigned char type = pdata[0]; 

     printf("WorkHandler::workLoop, type %d\n", type); 

     Packet *packet = m_packetFactory->createInstance(static_cast<PACKET_TYPES>(type)); 
     packet->fromByte(pdata); 

     delete work; 
    } 
} 

这是我处理工作的代码....我应该在这里还是两个地方删除工作实例?在此先感谢...

+0

在析构函数中。 – Mankarse

回答

1

你的代码第二位来看,它看起来像内存泄漏可能实际上是从Packet分配,因为Work实例在什么似乎是一个正确的位置被删除(在workLoopaddWork)。但是我不能确定没有看到更多的代码。

C++中的分配没有引用计数,因此在完成使用后应该删除Work实例。如果你事先删除它,它就消失了:使用该指针并且结果将是未定义的(可能工作,可能不会)。如果你不删除它,它会泄漏(如你所见)。

你应该重构你的代码使用智能指针 - 看的std ::的unique_ptr <>和std :: shared_ptr的<>(或升压:: scoped_ptr的<>和boost :: shared_ptr的<>)。他们将帮助确保事情在他们真的应该被删除时:

for(;;) 
{ 
    std::unique_ptr<int> uptr(new int); 
    std::shared_ptr<int> sptr = std::make_shared<int>(); 

    // uptr and sptr will be automatically deleted at this end of scope. 
} 
0

没有,这是灾难性的。 work指针仍在使用中,并且您正在使用它。这使它成为一个摇晃的指针。引用一个悬挂指针是未定义的行为

如果您不想管理对象的释放,请使用shared_ptr<>或其他智能指针。否则,delete它们在ServerManager::~ServerManager()之内,因为您仍将在m_workHandler之内引用它们。

1

如果要插入工作纳入队列和未完成尚未处理,你不希望在加入后立即将其删除。

你想要做的是仔细看看你的代码,当你不再需要你周围的对象时删除它。这通常是在您完成WorkHandler中的工作并将其安全地从队列中移除之后完成的。

1

addWork()中删除不会 - 你刚刚添加了对象,其他一些代码可能会开始访问它。如果你delete它现在你遇到未定义的行为。 workLoop()是一个更好的地方 - 你已经完成了对象的所有工作,看起来不再需要,所以你可以在这里删除它。

1

完成该操作后,您应该释放该对象(delete)。您不应该删除同一个对象两次。一旦你有delete一个对象,你不应该尝试通过其他指针访问它。

请记住,C++没有任何垃圾回收。所以没有引用计数。如果您使用newdelete,则需要手动处理自己的分配和释放。否则,您可以使用auto_ptr

1
  1. 如果你在第一个地方删除work你,最有可能,获取故障试图从指针不指向正确的对象读取,但标准说,这是UB,所以有可能是你的程序不会崩溃。
  2. 如果您在第二位删除work即可。

但更好的解决办法是将work一些智能指针,这将(离开while环路workloop后,你的情况)破坏后自动删除。为此,使用boost::shared_ptr<>

+0

'delete'不会空指针。从已删除的指针(并从空指针中读取)是未定义的 - 意味着它可能会崩溃或者它可能不会。 –

+0

@Cory Nelson固定 –