2013-03-10 2 views
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); 

ответ

2

При объявлении buf вы объявляете массив переменной длины . Это законно в C (от стандарта C99), но незаконно в C++. В C++ можно использовать вместо std::vector:

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

Вы можете использовать этот вектор в вызове recv, а также:

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

Чтобы использовать вектор внутри цикла, у вас есть два варианта :

  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); 
    } 
    
+0

Если я хочу использовать цикл while для получения множества изображений, как мне удалить содержимое 'buf' в конце каждого цикла? – askingtoomuch

+0

@boogiedoll См. Мой обновленный ответ. –

+0

отлично! благодаря :) – askingtoomuch

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

Это справедливо в C99 и называется массив в переменной длины. Если вы не используете C99, используйте malloc для выделения массива (и объявите buf как char *).

1

Вы должны использовать динамическое распределение памяти;

char* buf = new char[len]; 

Если вы закончите с помощью buf, не забудьте позвонить delete, чтобы освободить память.

delete[] buf; 
1

Пожалуйста выделить буфер через malloc т.е. buf = malloc(sizeof(char) * len);

1

Вы можете сделать это с новыми или таНос. Не забудьте удалить буфер, когда это будет сделано!

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 
1

Я написал класс под названием tempbuf именно для этой цели в C++.

Вы можете найти здесь:
small_lib.cpp
small_lib.h

Эти два файла 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].

Смежные вопросы