передать массив в качестве параметров в функцию

0

У меня есть функция, чтобы передать массив, и значение массива будет изменено в этой функции. Я реализую его следующим образом, но значения в массиве не изменяются после вызова функции. Может ли кто-нибудь помочь мне в этом? Благодарю!

Здесь я вызываю функцию, socket.Receive(sender,buffer,sizeof(buffer)). Переменный buffer не получает правильное значение.

while ( true )
{
    Address sender;
    unsigned char buffer[256];
    int bytes_read = socket.Receive( sender, buffer, sizeof( buffer) );
    if ( !bytes_read )
        break;
    printf("%d\n",buffer[92]);

}

Это код функции socket.Receive()

int Socket::Receive( Address & sender, 
                    void*  data, 
                    int size )
{
        unsigned char packet_data[256];

        unsigned int max_packet_size = 
            sizeof( packet_data );

#if PLATFORM == PLATFORM_WINDOWS
        typedef int socklen_t;
#endif

        sockaddr_in from;    
        socklen_t fromLength = sizeof( from );

        size = recvfrom( handle, 
            (char*)packet_data, 
            max_packet_size,
            0, 
            (sockaddr*)&from, 
            &fromLength );

        data = packet_data;
        unsigned int from_address = ntohl( from.sin_addr.s_addr );
        unsigned int from_port = ntohs( from.sin_port );

    return size;
}
  • 0
    Вы понимаете, что packet_data[256] - это массив переменных локальной области видимости, не так ли?
  • 0
    Какое значение оно получает, то?
Теги:
arrays
parameter-passing

3 ответа

2
Лучший ответ
data = packet_data;

На этой линии вы сопоставляя data, но параметр, который Receive занимает локальную копию указателя. Он должен взять ссылку, если вы пытаетесь изменить передаваемый аргумент:

int Socket::Receive( Address & sender, 
                    void*&  data, // <-- reference to a pointer
                    int size )

И, как сказал @DrewDormann, назначение не копирует данные из packet_data в data, а изменяет адрес, на который указывает data на адрес packet_data. Следствием этого является то, что при попытке повторного использования buffer декодирования позже вы получите Undefined Behavior для доступа к уже уничтоженному объекту.

Вместо этого следует использовать memcpy для копирования данных:

#include <cstring>
std::memcpy(data, packet_data, size);
2

У вас есть несколько ошибок, но проблема, о которой вы говорите, проистекает из этой строки.

        data = packet_data;

Эта строка не копирует весь массив packet_data. Он только перезаписывает data указателя новым адресом.

  • 0
    Так в чем же решение?
1

Я думаю, проблема заключается в том, что вы объявляете "unsigned char packet_data [256];" в стек вашей функции, и вы не копируете из нее байты в свой параметр "данные". Используйте memcpy для копирования содержимого "packet_data" в "данные". Вместо этого вы назначаете "данные" в "packet_data", когда вы делаете это, "данные" указывают на ту же память, что и "packet_data". Но как только функция выйдет, "packet_data" освобождается, поэтому содержимое становится мусором. Следовательно, вы не видите данные в указателе "данные". Надеюсь, это было полезно.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню