C++ 如何正确传递指针
编辑:我更改了标题,因为它不适合问题,因为C++ 如何正确传递指针,c++,new-operator,C++,New Operator,编辑:我更改了标题,因为它不适合问题,因为新的操作员不是问题。以前的标题是“新操作员可以失败吗?” 在下面的代码中,在客户端连接到服务器之前,我创建了一个新的套接字对象指针。当客户端连接时,我使用new创建对象。但不知何故,当我使用调试器(EclipseCDT,g++Ubuntu/Linaro 4.6.3-1ubuntu5)逐步检查代码时,我发现在调用new操作符之后,指针仍然为空 class Socket { public: Socket( int domain, int type,
新的
操作员不是问题。以前的标题是“新操作员可以失败吗?”
在下面的代码中,在客户端连接到服务器之前,我创建了一个新的套接字对象指针。当客户端连接时,我使用new
创建对象。但不知何故,当我使用调试器(EclipseCDT,g++Ubuntu/Linaro 4.6.3-1ubuntu5)逐步检查代码时,我发现在调用new
操作符之后,指针仍然为空
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;
}
类套接字
{
公众:
套接字(int域,int类型,int协议=0);
~Socket();
[...]
int接受(套接字*套接字);
[...]
私人:
套接字();
int-mSocketDescriptor;
int-mNetworkProtocol;
int-mTransportProtocol;
};
[...]
int套接字::接受(套接字*套接字)
{
//接受一个连接(阻塞)
cli_addr中的结构sockaddr_;
socklen\u t clilen=sizeof(cli\u addr);
int-ret=::accept(mSocketDescriptor,(struct sockaddr*)和cli_addr,&clilen);
如果(ret>=0){
socket=new socket();//如果您使用的是旧编译器(从上个千年开始)或在禁用异常的模式下编译,则对象的new
ing结果可能为空。对于当代编译器,如果内存分配失败,将引发异常
从您的代码判断,您确定new
返回null吗?…因为您将指针分配给一个按值传递而不是按引用传递的变量,也就是说,更改仅在函数中可见。简短的回答是yes。当它执行时,可能会失败并引发std::bad_alloc
异常这应该发生在任何启用了异常的现代编译器上
但是,如果您使用的是非常旧的编译器,或者禁用了异常,则新的操作符可能会自动失败
另外,刚刚注意到这一点-您不应该使用socket=new socket();
来使用空白构造函数。请改用socket=new socket;
。注意缺少的括号
另一件需要担心的事情(在你的情况下不是很确定,只是把它扔出去,以防万一)是。它真的会以奇怪的、意想不到的方式把事情搞得一团糟,而且一开始要花很长时间才能找到它。好的,这个问题的解决方案是,正如hmjd所说的:
我想你是说newConn在调用者中仍然为NULL?如果是,请通过引用传递指针,因为指针的副本正在传递给accept(),因此任何更改都是accept()函数的局部更改
不幸的是,我的调试器将我引导到了错误的方向,显示套接字指针注释甚至在本地更改。但是,当通过引用传递指针时,一切正常。您使用的是旧编译器还是无异常编译?尝试使用nothrow new并检查它是否返回NULL
。我想您的意思是newConn
是调用者中仍然NULL
?如果是,请通过引用传递指针,因为指针的副本正在传递给accept()
,因此任何更改都是accept()的本地更改
函数。在Pubby:不,至少我没有设置它。在tenfour:你现在知道的德语单词:D。在hmjd:好的,但如果我的调试器不是开玩笑的话,指针甚至不会在本地更改。调试器有时会出错,特别是在你使用优化编译的情况下。socket=new socket;
调用ctor吗?它怎么知道是什么选择哪一个?或者这条经验法则仅适用于没有参数的ctor吗?当您这样做时,您只需调用无参数的ctor,它是可用的。
// 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);
}