【问题标题】:C: memcpy segfault with void* pointersC:带有 void* 指针的 memcpy 段错误
【发布时间】:2014-12-15 18:10:23
【问题描述】:

代码——主循环:

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。 欢迎任何建议或cmets!

【问题讨论】:

  • 你需要使用recv(listenSocket, Buffer, INET_BUFFER_SIZE, 0); -- 在Buffer之前没有&amp;
  • 我在 10 秒前确实意识到了这一点。这让我保持了一段时间。婴儿步。感谢您的回复!

标签: c segmentation-fault malloc memcpy


【解决方案1】:

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

recv 的调用中删除与号应该可以解决这个问题:

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

一般来说,最好使用内存分析器(例如 valgrind)来诊断此类情况。该工具会立即告诉您Buffer 写入对堆栈区域的写入无效,并且随后将接收到的数据作为指针取消引用(现在导致 SIGSEGV 的问题)是无效读取。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-12
    • 2016-09-02
    • 1970-01-01
    • 1970-01-01
    • 2021-02-13
    • 1970-01-01
    相关资源
    最近更新 更多