2

编辑:我更改了标题,因为它几乎不适合问题,因为new操作员不是问题。以前的标题是“新操作员会失败吗?”

在下面的代码中,在客户端连接到服务器之前,我创建了一个新的 Socket 对象指针。当客户端连接时,我使用new. 但不知何故,当我使用调试器(Eclipse CDT,g++ Ubuntu/Linaro 4.6.3-1ubuntu5)单步执行代码时,我发现在调用new操作员之后指针仍然为 NULL。

class Socket
{
public:
    Socket( int domain, int type, int protocol = 0 );
    ~Socket();
    [...]
    int accept( Socket * socket );
    [...]
private:
    Socket();
    int mSocketDescriptor;
    int mNetworkProtocol;
    int mTransportProtocol;
};

[...]

int Socket::accept( Socket * socket )
{
    // Accept one connection (blocking)
    struct sockaddr_in cli_addr;
    socklen_t clilen = sizeof(cli_addr);
    int ret = ::accept(mSocketDescriptor, (struct sockaddr *) &cli_addr, &clilen);
    if ( ret >= 0 ){
        socket = new Socket();  // <- Here's the problem, socket remains NULL
        socket->mSocketDescriptor  = ret;
        socket->mNetworkProtocol   = this->mNetworkProtocol;
        socket->mTransportProtocol = this->mTransportProtocol;
    }
    return ret;
}

主循环:

// Accept all incoming connections in a loop
while(true){

    // Accept one connection (blocking)
    net::Socket * newConn = NULL;
    if (socket.accept(newConn) < 0){
        perror("accept()");
        exit(EXIT_FAILURE);}

    // Create a new thread that is talking to the client
    pthread_t nThreadID;
    pthread_create(&nThreadID, NULL, ClientMainThreadProc, newConn);
}

我通读了 C++ 参考资料。new它告诉我如果失败应该引发 bad_alloc 异常。但这不是事实,所以我不知道出了什么问题。有什么建议么?

4

3 回答 3

1

好的,问题的解决方案是,正如 hmjd 所说:

我想你的意思是 newConn 在调用者中仍然是 NULL ?如果是这样,则通过引用传递指针,因为指针的副本被传递给accept(),因此任何更改都对accept() 函数是本地的。

不幸的是,我的调试器把我引向了错误的方向,显示套接字指针注释甚至在本地发生了变化。但是当通过引用传递指针时,一切正常。

于 2012-11-12T10:20:42.990 回答
0

如果您使用的是旧编译器(来自上一千年)或在禁用异常的模式下编译,则new对象的结果可能为空。对于现代编译器,如果内存分配失败,则会引发异常。

从您的代码来看,您确定new返回 null 吗?...因为您将指针分配给通过值而不是通过引用传递的变量,即更改仅在函数内可见。

于 2012-11-12T10:05:04.033 回答
0

简短的回答是肯定的。C++ new 运算符可能会失败并在失败时抛出std::bad_alloc异常。这应该发生在任何启用了异常的现代编译器上。

但是,如果您使用的是相当旧的编译器,或者您禁用了异常,则new操作员可能会默默地失败。

此外,刚刚注意到这一点 - 您不应该socket = new Socket();使用空白构造函数。改为使用socket = new Socket;。注意缺少的括号!

另一件要担心的事情(在你的情况下不太确定,只是把它扔在那里,以防万一)是heap corruption。它真的会以奇怪的、意想不到的方式把事情搞砸,而且最初需要很长时间才能找到。

于 2012-11-12T10:16:23.440 回答