【问题标题】:C++ dynamic array causes segmentation fault at assignmentC ++动态数组在分配时导致分段错误
【发布时间】:2012-09-15 15:35:11
【问题描述】:

我正在做一个使用套接字的应用程序,所以我将套接字句柄保存在一个数组中。我有以下代码:

while(0 == 0){
    int * tx = (int*)(malloc((nr_con + 2) * sizeof(int)));
    if (conexiuni != NULL)
    {
        syslog(LOG_NOTICE,"Ajung la eliberare %d",nr_con);
        memcpy(&tx[0],&conexiuni[0],(sizeof(int) * (nr_con)));
        syslog(LOG_NOTICE,"Ajung la eliberare %d",nr_con);
        free(conexiuni);
    }
    conexiuni = tx;

    syslog(LOG_NOTICE,"Ajung la mama %d",nr_con);
    //The line bellow causes a segfault at second connection
    if ((conexiuni[nr_con] = accept(hsock,(sockaddr*)(&sadr),&addr_size)) != -1)
    {
        nr_con++;
        syslog(LOG_NOTICE,"Primesc de la %s",inet_ntoa(sadr.sin_addr));
        syslog(LOG_NOTICE,"kkt %d",conexiuni[nr_con - 1]);
        int * sz = (int*)malloc(sizeof(int));
        *sz = conexiuni[nr_con - 1];
        syslog(LOG_NOTICE,"after %d",*sz);
        pthread_create(&tidi,0,&ConexiuniHandler, sz);
    }
}

当我分配数组时第二次连接时,程序崩溃。我究竟做错了什么?我在 Windows 上尝试了相同的代码,它运行良好,但在 Linux 上它崩溃了。

【问题讨论】:

  • 在 C++ 中使用 new 而不是 malloc。
  • 请提供更多信息,说明您要完成的工作。这个来源没有多大意义。看起来你有一个无限循环,当你接受连接时,你正在分配内存来存储套接字句柄,所以它是某种接受连接然后启动线程来处理套接字连接的服务器?
  • @opc0de: 因为malloc 保留只是为了向后兼容 c。 C++ 代码应该使用new。
  • @Dani,老实说,甚至不要使用它。使用向量。对非数组news 也使用智能指针。
  • new 具有面向对象编程的附加特性,为它的使用提供了比 malloc() 更简洁的接口。 malloc() 只是分配内存。 new 为 C++ 对象调用构造函数和其他好东西。

标签: c++ pointers segmentation-fault


【解决方案1】:

使用std::vector。

一个封装动态大小数组的序列容器。

【讨论】:

    【解决方案2】:

    我假设您想要做的是拥有一个接受连接的服务器,然后当连接被接受时,您启动一​​个线程来处理该连接请求。所以每次你接受你都想启动一个线程并给它套接字句柄。您还可以跟上数组中的所有套接字句柄,当您接受新的连接请求时,该句柄会动态增加。

    以下是建议的方法。我没有做任何测试,也没有编译这个代码段,但它是一个开始的地方。我正在做的一件事是每次调整数组大小时将套接字句柄数组增加 16 个块。我这样做是因为它可以使内存管理器的工作更轻松一些,并通过减少对malloc() 的调用次数来减少碎片量。

    int nr_con = 0;      // we start off with no connections
    int block_con = 16;  // number of blocks to allocate each time we increase the array
    SOCKET  *conexiuni = malloc ((nr_con + block_con) * sizeof(SOCKET));
    while(1) {
        syslog (LOG_NOTICE, "Ajung la mama %d", nr_con);
    
        // wait for a connection request to come in.  if it does, log the request
        // then create a thread to handle the request providing the socket to the thread.
        // we are keeping an array of the sockets that is dynamically increased so
        // we will allocate blocks of 16 at a time as we lengthen the array.
        if ((conexiuni[nr_con] = accept (hsock, (sockaddr*)(&sadr), &addr_size)) != -1)
        {
            block_con--;
            if (block_con < 1) {
            {
                // so lets add another block to our array by allocating the memory
                // then copying the current array to the new memory area then freeing
                // the old memory area which is no longer needed.
                block_con = 16;
                SOCKET *pTemp = malloc(nr_con + block_con) * sizeof(SOCKET));
                syslog (LOG_NOTICE, "Ajung la eliberare %d", nr_con);
                memcpy (pTemp, conexiuni, (sizeof(SOCKET) * (nr_con + 1)));
                syslog (LOG_NOTICE, "Ajung la eliberare %d", nr_con);
                free (conexiuni);
                conexiuni = pTemp;
            }
            syslog (LOG_NOTICE, "Primesc de la %s", inet_ntoa(sadr.sin_addr));
            syslog (LOG_NOTICE, "kkt %d", conexiuni[nr_con]);
    
            SOCKET  *sz = conexiumi + nr_con;
            syslog (LOG_NOTICE, "after %d", *sz);
    
            // start the thread which is to service this connection request.
            pthread_create (&tidi, 0, &ConexiuniHandler, sz);
            nr_con++;
        }
    }
    

    但是,这样的事情存在一些问题。首先,在上面的示例中,如果 malloc() 由于无法提供内存请求而返回 NULL 指针,我不会处理内存不足错误。

    第二个问题是在动态扩展数组之前线程可能不会访问指向套接字的指针,从而导致提供的指针无效,因为它在动态重新分配期间被释放。因此,如果您有大量连接快速进入,这可能是个问题。线程至少应该做的第一件事是制作套接字句柄的本地副本。

    另一个问题是,您将如何返回数组以确定哪些套接字仍然有效且打开,哪些套接字在连接关闭时是陈旧的。您是否只是在连接请求进入时动态分配空间,直到您的服务器启动并运行几天后内存不足?

    你真的应该使用 SOCKET 而不是使用 int,因为它是实际的数据类型。我意识到在大多数情况下,SOCKET 实际上是一个 int,但是在这些问题上通常最好是精确的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多