Problem with string and segmentation fault in UDP sockets

I am doing unix network programming over cygwin. I am trying to receive an object via the recvfrom() function (I am using UDP sockets). The class definition of that object is :

class Message{
public:
int ID;
int seq;
string *s;
};

Message::Message(){
s = new string();
}

The object sending is fine. The receive operation looks fine but There is a problem. I am giving you the code:

Message *m = new Message();

bytes_read = recvfrom(sock , (Message *) m , 48 , 0 ,(struct sockaddr *)&temp_neighbor_addr, &addr_len);

cout<<bytes_read; cout<<m->s->size();

The bytes_read = 48 (this is ok).
But the.....cout<<m->s->size();....causes segmentation fault. The error looks like this:

6 [main] router 596 _cygtls::handle_exceptions: Error while dumping state (probably corrupted stack)
Segmentation fault (core dumped)

And sometimes the value of s->size shows a huge number (4460419 something like this).

But the message I am sending using sendto is:

Message *hello = new Message();
hello->ID = 0;
hello->seq = ++currentSEQ;
hello->s = new string("HhhhhhhhhHhhhhhhhhhHhhhhhhhhhHhhhhhhhhhH");
int messageSize = sizeof(hello->ID) + sizeof(hello->seq) + hello->s->length();

sendto(sock, (Message *) hello , messageSize, 0 , (struct sockaddr *) &bcast_addr , sizeof(struct sockaddr));

where bcast_addr is 255.255.255.255.

The message is being received but after reception,m->s as well as m->s->size() are causing the segmentation fault problem.

Can anyone help me resolving this issue?

Thanks in advance....
Last edited on
You're overwriting the object s. When you try to dereference s you're probably addressing memory outside your address space (if you're lucky). In fact, it would be worse if the program didn't crash because then you'd be trashing memory in your program.

You have to serialise/deserialise your object if you want to sent it over a link.

Are you aware of the implications of passing such a structure with an unreliable protocol?
A common(and dirty) way to achieve the serialization/deserialization you want in C is to create a struct along the lines of:
1
2
3
4
5
6
struct packet {
uint32_t id;
uint32_t seq;
uint8_t data[1];
};
/* add the proper attribute for your compiler to ensure no padding(eg. __attribute__((packed))" for gcc) */


Notice the data-arry with a size of one. The trick here is that you can allocate a memblock of needed size and cast it to the packet struct. Now you can access the data using the array index by deliberatly indexing "out of bounds". Example:
1
2
3
4
5
6
7
8
9
/* A packet with a data section of 100 bytes */
struct packet *my_packet = (struct packet *)malloc(sizeof(struct packet) + 99);
my_packet->id = htonl(the_id_to_use);
my_packet->seq = htonl(the_seq_to_use);
memcpy(my_packet->data, the_data_to_add, 100);
/* Random access to data using array index */
my_packet->data[34] = 0xff;
/* xmit */
send(my_sock, my_packet, sizeof(struct packet) + 99, 0);


Now on the recieving end you can cast a recieve buffer to the packet struct, do the needed byte conversions and your ready :-)

This is not the cleanest way of doing [de]serialization, but it can be convenient IMHO.

Topic archived. No new replies allowed.