У меня есть функция, чтобы передать массив, и значение массива будет изменено в этой функции. Я реализую его следующим образом, но значения в массиве не изменяются после вызова функции. Может ли кто-нибудь помочь мне в этом? Благодарю!
Здесь я вызываю функцию, 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;
}
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);
У вас есть несколько ошибок, но проблема, о которой вы говорите, проистекает из этой строки.
data = packet_data;
Эта строка не копирует весь массив packet_data
. Он только перезаписывает data
указателя новым адресом.
Я думаю, проблема заключается в том, что вы объявляете "unsigned char packet_data [256];" в стек вашей функции, и вы не копируете из нее байты в свой параметр "данные". Используйте memcpy для копирования содержимого "packet_data" в "данные". Вместо этого вы назначаете "данные" в "packet_data", когда вы делаете это, "данные" указывают на ту же память, что и "packet_data". Но как только функция выйдет, "packet_data" освобождается, поэтому содержимое становится мусором. Следовательно, вы не видите данные в указателе "данные". Надеюсь, это было полезно.
packet_data[256]
- это массив переменных локальной области видимости, не так ли?