C:带有void *指针的memcpy段错误

时间:2014-10-20 17:06:12

标签: c segmentation-fault malloc memcpy

代码 - 主循环:

int handleClient (struct clientData* clientData)
{
    void* Buffer = malloc (INET_BUFFER_SIZE); <-- VOID* BUFFER FOR RECV()
    int listenSocket = clientData->listenSocket;
    struct sockaddr_in clientAddress = clientData->clientAddress;

    printf("Received connection from client %s:%d.\n", inet_ntoa(clientAddress.sin_addr), ntohs(clientAddress.sin_port));

while (1)
{
    int packetSize;
    if ((packetSize = recv(listenSocket, &Buffer, INET_BUFFER_SIZE, 0)) > 0)
    {
        if (packetSize == ECHO_SIZE)
        {
            handleEchoPacket(Buffer);
            continue;
        }

        if (packetSize == MESSAGE_SIZE) <---THIS IS TRIGGERED BECAUSE OF PACKET SIZE
        {
            handleMessagePacket(Buffer);
            continue;
        }
    }
}

代码 - handleMessagePacket(void * Buffer):

void handleMessagePacket (void* Buffer)
{

    void* localBuffer = (void*) malloc(INET_BUFFER_SIZE);
    memcpy(localBuffer, Buffer, INET_BUFFER_SIZE); <--SEGFAULT
    (...)
}

GDB - 部分输出:

Program received signal SIGSEGV, Segmentation fault.
__memcpy_sse2_unaligned () (.....) <--Tells me it doesn't have source files, not relevant to the problem.

基本上,当我将一个内存块从void指针复制到本地缓冲区时,就会出现问题。两者都是相同类型的malloc()堆内存:void。 欢迎任何建议或意见!

1 个答案:

答案 0 :(得分:1)

以下是正在发生的事情:当您将Buffer的地址传递给recv时,接收的数据将被放置在分配给缓冲区地址的空间中,该地址位于堆栈中。当您随后致电handleMessagePacket时,您传递的地址不再有效:已由recv覆盖!

recv的调用中删除&符应该可以解决此问题:

if ((packetSize = recv(listenSocket, Buffer, INET_BUFFER_SIZE, 0)) > 0)
//                                  ^^ No ampersand

通常,像这样的情况最好用内存分析器诊断,例如valgrind。该工具会立即告诉您写入Buffer写入的堆栈区域无效,并且后续取消引用接收数据作为指针(现在导致SIGSEGV的问题)是无效读取。