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++ リファレンスを読みました。失敗した場合、bad_alloc 例外が発生する必要があることがわかりnewます。しかし、それは事実ではないので、何がうまくいかないのかわかりません。助言がありますか?

4

3 に答える 3

1

hmjdが述べたように、問題の解決策は次のとおりです。

呼び出し元で newConn がまだ NULL であることを意味していると思いますか? その場合は、ポインターのコピーが accept() に渡されるため、参照によってポインターを渡します。これにより、すべての変更が accept() 関数に対してローカルになります。

残念ながら、私のデバッガーは私を間違った方向に誘導し、ソケットポインターのメモがローカルで変更されたことさえ示しました。しかし、参照によってポインターを渡すと、すべてが正常に機能します。

于 2012-11-12T10:20:42.990 に答える
0

(前のミレニアムからの)古いコンパイラを使用している場合、または例外が無効になっているモードでコンパイルするnew場合、オブジェクトのingの結果はnullになる可能性があります。最新のコンパイラでは、メモリ割り当てが失敗すると例外がスローされます。

あなたのコードから判断すると、それnewはnullを返しますか?...参照ではなく値で渡される変数にポインタを割り当てるため、つまり、変更は関数内でのみ表示されます。

于 2012-11-12T10:05:04.033 に答える
0

短い答えはイエスです。C++のnew 演算子は失敗し、失敗std::bad_allocしたときに例外をスローする可能性があります。これは、例外が有効になっている最新のコンパイラで発生するはずです。

ただし、かなり古いコンパイラを使用している場合、または例外を無効にしている場合、newオペレーターサイレントに失敗する可能性があります。

また、これに気付きました-socket = new Socket();空のコンストラクターを使用しないでください。socket = new Socket;代わりに使用してください。括弧がないことに注意してください。

心配するもう1つのこと(あなたの場合はよくわかりませんが、念のため、そこに捨ててください)はヒープ破損です。奇妙で予期しない方法で物事を台無しにする可能性があり、最初は追跡に永遠に時間がかかります.

于 2012-11-12T10:16:23.440 に答える