0

ソケットからバッファバイトを読み取っていますが、長さ情報を使用してバッファ配列を初期化する方法がわかりません。

uint32_t len;
int lengthbytes = 0;
int databytes = 0;

// receive the length info of an image data
lengthbytes = recv(clientSocket, (char *)&len, sizeof(len), 0);

// convert hexadecimal data to length in bytes
len = ntohl(len);

// ????? how to initialize the buffer array with the length info ????
char buf[len];   -----> this is illegal in C  

// read the image data 
databytes = recv(clientSocket, buf, sizeof(buf), 0);
4

7 に答える 7

4
len = ntohl(len);
char buf[len];  //----> this is illegal in C  

これはC99で有効であり、可変長配列と呼ばれます。C99を使用していない場合は、を使用mallocして配列を割り当てます(およびとして宣言bufしますchar *)。

于 2013-03-10T16:17:38.023 に答える
2

宣言するときはbuf可変長配列を宣言します。これは(C99標準からの)Cでは合法ですが、C++では違法です。C ++では、代わりに次を使用できますstd::vector

std::vector<char> buf(len);

次の呼び出しでもこのベクトルを使用できますrecv

databytes = recv(clientSocket, &buf[0], buf.size(), 0);

ループ内でベクトルを使用するには、次の2つの選択肢があります。

  1. ループの外側で変数を宣言し、必要に応じて使用clearします。resize

    std::vector<char> buf;
    
    // ...
    
    for (int i = 0; i < number_of_images; i++)
    {
        std::cout << "Fetching image #" << (i + 1) << '\n';
    
        // Get the image length
        size_t length = get_image_length();
    
        buf.clear();  // Clear the buffer
        buf.resize(length);  // Set the size to the image length
    
        // Receive the image
        databytes = recv(clientSocket, &buf[0], buf.size(), 0);
    }
    
  2. ベクトルをループ内でローカルになるように宣言します。

    for (int i = 0; i < number_of_images; i++)
    {
        std::cout << "Fetching image #" << (i + 1) << '\n';
    
        // Get the image length
        size_t length = get_image_length();
    
        std::vector<char> buf(length);
    
        // Receive the image
        databytes = recv(clientSocket, &buf[0], buf.size(), 0);
    }
    
于 2013-03-10T16:18:22.933 に答える
1

動的メモリ割り当てを使用する必要があります。

char* buf = new char[len];

を使い終わったら、メモリを解放するbufために呼び出すことを忘れないでください。delete

delete[] buf;
于 2013-03-10T16:17:41.887 に答える
1

mallocieを介してバッファを割り当ててくださいbuf = malloc(sizeof(char) * len);

于 2013-03-10T16:18:13.140 に答える
1

newまたはmallocでそれを行うことができます。完了したら、バッファを削除することを忘れないでください!

于 2013-03-10T16:18:17.890 に答える
1

tempbufこの目的のために正確に呼び出されるクラスを C++ で作成しました。

ここで見つけることができます:
small_lib.cpp
small_lib.h

これら 2 つのファイルは MIT ライセンスなので、好きなように使用できます。

このクラスの使い方は?

tempbuf buf(len);
databytes = recv(clientSocket, buf.get(), buf.size(), 0); // if you want char* returned
databytes = recv(clientSocket, buf.constchar(), buf.size(), 0); // if you want constchar* returned

そして、なぜ私がこのクラスを書いたと思いますか? クラスのデストラクタで行われるため、動的に割り当てられたメモリを削除または解放する必要はありません。

なぜ使用しなかったのstd::auto_ptrですか?私の理解では、それはサポートされているがサポートされてnew Xいないため、配列以外の場合のみですnew X[10]

于 2013-03-10T16:34:54.370 に答える
1

を使用してstd::vector<char>、それをdata()配列バッファとして使用できます。

#include <vector>
std::vector<char> buf(len);
databytes = recv(clientSocket, buf.data(), buf.size(), 0); // access underlying char array
databytes = recv(clientSocket, &buf[0], buf.size(), 0);    // as above, C++03 version
于 2013-03-10T16:18:39.577 に答える