如何正确传递指针

时间:2012-11-12 09:56:46

标签: c++ new-operator

编辑 :我更改了标题,因为它几乎不适合问题,因为new运算符不是问题。以前的标题是“Can operator new fail?”

在下面的代码中,在客户端连接到服务器之前,我创建了一个新的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异常。但这不是事实,所以我不知道什么是错的。有什么建议吗?

3 个答案:

答案 0 :(得分:1)

好的问题是,正如hmjd所说:

  

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

不幸的是,我的调试器操纵了我错误的方向,显示套接字指针注意甚至在本地更改。但是当通过引用传递指针时,everthing工作正常。

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

然而如果您使用的是相当旧的编译器,或者您已禁用例外,new运算符可以无声地失败。

另外,只是注意到了这一点 - 你不应该使用socket = new Socket();来使用空白构造函数。请改用socket = new Socket;。请注意缺少的括号!

另一件需要担心的事情(在你的情况下不太确定,只是为了以防万一)将它扔出去是heap corruption。它可能会以奇怪的,意想不到的方式搞砸事情,最初需要永远跟踪。