3

サーバー上のクライアントからのメッセージを受け入れるプログラムを C++ で作成しようとしています。ただし、最初にクライアントがメッセージのサイズを送信し、この値を使用して、サーバーは最終的に送信されたときにメッセージを格納するための文字の配列を作成します。メッセージ サイズの値を使用して配列を初期化しようとすると、コンパイラは messageSize 整数が定数値でなければならないためエラーがあると表示します。整数型の配列の長さ:

//Deal with data in DNS style
int dnsStyle()
{   
    recv(clientSocket, bufferSize, 1, MSG_WAITALL);
    return bufferSize[0];
}

//Communicate in the DNS style of addressing
char DNS()
{
    int messageSize = dnsStyle();
    printf("The message buffer has been tailoured to this size: '%d'", messageSize);
    char bufferMessDNS[messageSize];
    //Then recieve the actual message itself
    recv(clientSocket, bufferMessDNS, messageSize, MSG_WAITALL);
    //Then send the message back to client
    send(clientSocket, bufferMessDNS, messageSize, 0);

    //std::string returnMess = "OK";
    //send(clientSocket, sendBack.c_str(), sendBack.size(),0);
}
4

5 に答える 5

3

C++ では、拡張機能のない適合 C++ について話していることに注意してください。自動配列は、コンパイル時に既知のサイズで割り当てられます。これは、配列のサイズがコンパイル時に既知である必要があるためです。

したがって、このコード:

char bufferMessDNS[messageSize];

変更される可能性があるため、形式が正しくありませんmessageSize

さまざまなサイズの配列が必要な場合は、vector <char>.

messageSize次のように、いわゆる整数定数式を作成すると、上記のコードを機能させることができます。

const size_t messageSize = 256;
char bufferMessDNS[messageSize];

しかし、ここではバッファのサイズは常に正確に 256 バイトです。これは正しいサイズになることはほとんどないと確信しています。

必要に応じて、以下を使用して動的サイズの配列を使用することもできますnew[]

char* bufferMessDNS = new char [messageSize]

しかし、これにより新たな問題が山積みになり、割り当てたばかりのメモリの所有権を管理することはもちろんのことです。今、あなたはそれをdeleteしなければなりません:

delete [] bufferMessDNS;
于 2013-10-11T18:29:34.467 に答える
2

John Diblings answerを拡張するにstd::vector<char>は、バッファとしてan を使用する必要があります。これがどのように機能するかです:

char DNS()
{
    std::vector<char>::size_type messageSize = dnsStyle(); // use correct type
    printf("The message buffer has been tailoured to this size: '%d'", messageSize);
    std::vector<char> bufferMessDNS(messageSize); // create vector with correct size
    //Then recieve the actual message itself
    recv(clientSocket, &bufferMessDNS[0], messageSize, MSG_WAITALL);
    //Then send the message back to client
    send(clientSocket, &bufferMessDNS[0], messageSize, 0);

    //std::string returnMess = "OK";
    //send(clientSocket, sendBack.c_str(), sendBack.size(),0);
}

ここで最も重要な部分は、 as パラメータstd::vectorを取るコンストラクタを呼び出して、正しいサイズでを初期化することです。size_typeバッファを渡すにrevcは、 の最初の要素のアドレスを取得するだけですstd::vector

于 2013-10-11T18:52:27.860 に答える
0

コンパイル時に解釈できるサイズでのみ配列を宣言する必要があります。つまり、intリテラル ( char bufferMessDNS [100]) にするか、マクロ ( など#define MSG_SIZE 100) を使用するか、const int.

あなたの目的のために、実行時にのみサイズを知ることができるので、

char *bufferMessDNS = new char[messageSize];
....
delete []bufferMessDNS
于 2013-10-11T18:30:14.393 に答える
0

問題は、コンパイラがコンパイル時にスタック上に作成されたすべての変数のサイズを知る必要があることです->コンパイル時に既知のサイズの配列のみを割り当てることができます

サイズが実行時にのみわかっている場合は、動的メモリ割り当てを使用できます。すなわち:

char bufferMessDNS[messageSize];
// replace with
char* bufferMessDNS = new char[messageSize];

// and at the end of your function don't forget to release the memory
delete[] bufferMessDNS;

コンパイル時にコンパイラがスタック変数のサイズを知る必要がある理由の詳細な回答については、次の投稿を参照してください: Why does a C/C++ compiler need the size of an array at compile time?

于 2013-10-11T19:12:25.810 に答える