使用winsock发送缓冲区后可以删除内存吗?

Posted

技术标签:

【中文标题】使用winsock发送缓冲区后可以删除内存吗?【英文标题】:Can I delete the memory after I send the buffer using winsoc? 【发布时间】:2017-05-16 11:08:06 【问题描述】:

我有程序需要将缓冲区发送到套接字。我的问题是我可以在调用 Winsock->send() 方法后立即删除缓冲区吗?

我提出这个问题的原因:我使用 Windbg 工具来识别内存泄漏,它在BuildPacket() 中显示了这个地方,新内存没有正确释放。 所以我想在发送到套接字后清除内存。 当我的程序在多个循环中运行时,此方法将被调用大约 4,00,000 次,这会消耗大部分内存。

请。假设m_ClientSocket 是一个已经建立的套接字连接。

bool TCPSendBuffer(char* pMessage, int iMessageSize)

    try 
        int iResult = 0;
        iResult = send(m_ClientSocket, pMessage, iMessageSize, 0);
        if (iResult == SOCKET_ERROR)
            // Error condition
            m_iLastError = WSAGetLastError(); 
            return false;
        
        else
            // Packet sent successfully
            return true;
        
    
    catch (int ex)
        throw "Error Occured during TCPSendBuffer";
    


int BuildPacket(void* &pPacketReference)

    TempStructure* newPkt = new TempStructure();

    // Fill values in newPkt here

    pPacketReference = newPkt;
    return sizeof(TempStructure);


bool SendPackets()

    void* ref = NULL;
    bool sent = false;
    int size = BuildPacket(ref);

    sent = TCPSendBuffer((char*)ref, size);

    // Can I delete the ref here...?
    delete ref;

    return sent;


struct TempStructure

    UINT32 _Val1;
    UINT32 _Val2;
    UINT32 _Val3;
    UINT32 _Val4;
    UINT32 _Val5;
    UINT32 _Val6;
    UINT8 _Val7;
    UINT16 _Val8;
    UINT16 _Val9;
    UINT16 _Val10;
    UINT32 _Val11[16];
    UINT32 _Val12[16];
    bool _Val13[1024];
;

请提供任何可能的解决方案。谢谢。

【问题讨论】:

您可以而且必须在发送操作完成后删除缓冲区。在同步调用的情况下 - 就在函数返回之后。以防异步调用 - 通常在回调中,在操作完成时执行 【参考方案1】:

它可能在BuildPacket 中指代您的new,因为您没有delete 它,但您确实将它分配给另一个指针并且被释放,因此它很可能是误报。

但是,更成问题的是您的代码中有未定义的行为,即:

void* ref = NULL;
delete ref;

void* 上调用delete 是未定义的行为,您应该在删除它之前强制转换它。

【讨论】:

代替void*,我可以拥有结构本身TempStructure* ref = NULL;。所以删除这个应该清除创建的内存吧? 感谢老板@Gill Bates。所以删除不会影响已经正确发送的数据。那是我唯一的担心。谢谢你的时间。 :)

以上是关于使用winsock发送缓冲区后可以删除内存吗?的主要内容,如果未能解决你的问题,请参考以下文章

丢弃用于 TCP 连接的 winsock 内部缓冲区中的排队数据

在 WinSock 中通过 127.0.0.1 发送的多播可以用 INADDR_ANY 读取吗?

用VB的Winsock来发送http请求头,请指教!

我们可以在 DLL DETACH 中初始化 Winsock 吗?实际上我想在进程终止时发送一些数据(DLL DETACH)

vb以二进制打开excel后用winsock发送,结果接收后打开的是乱码,发送别的文件没问题,为啥?

在 C++ 中的 Winsock 中发送 HTTP GET 请求后,Recv() 函数挂起