11 Replies - 421 Views - Last Post: 07 July 2013 - 10:55 PM Rate Topic: -----

#1 robgeek  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 104
  • Joined: 15-January 13

Segmentation fault error in linked lists.

Posted 06 July 2013 - 04:56 PM

Good evening, guys. I'm trying to make a program that communicates with another program via socket. The server program receives a node of a linked list and inserts it in a linked list head. After adding the node, it sends the complete list right back to the client. The client creates a node and sends to the server, and receives the list mounted.
The error is happening when I try to show the full list on the client. The client only receives the server's head but misses the reference list of the next node, and thus the rest of the list! How can I solve this problem? There is no error in the insertion algorithm of the list, because I tested it in a single program and it works. The problem is that I get the server node head, and he doesn't holds the address of the next node.
typedef struct list {
	int hour, id;
	struct list *ant, *prox;
}List;

//Server.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/stat.h>
#include "tasks.h"

#define SOCK_PATH "socket_comm"

int main( ) {

	int descServer1, descServer2;
	struct sockaddr_un server, client;

	//Create the head of he list.
	List *list = ( List * )malloc( sizeof( List ) );
	list->hour = 888;
	list->ant = NULL;
	list->prox = NULL;


	if( ( descServer1 = socket( AF_UNIX, SOCK_STREAM, 0 ) ) == -1 ) {
		perror("Server ");
		return 1;
	} 

	memset( &server, 0, sizeof( struct sockaddr_un ) );
	server.sun_family = AF_UNIX;
	strcpy( server.sun_path, SOCK_PATH );
	unlink( server.sun_path );

	if( bind( descServer1, ( struct sockaddr * )&server, sizeof( struct sockaddr_un ) ) == -1 ) {
		perror("Server ");
		return 1;
	}

	if( listen( descServer1, 5 ) == -1 ) {
		perror("Server ");
		return 1;
	}

	printf("Server created.\n");

	while( 1 ) {
		int done, size;
		int sizeClient = sizeof( client );
		if( ( descServer2 = accept( descServer1, ( struct sockaddr * )&client, &sizeClient ) ) == -1 ) {
			perror("Server ");
			return 1;
		}
		
		done = 0;
		do {
			List *node = ( List * )malloc( sizeof( List ) );
			size = recv( descServer2, node, sizeof( List ), 0 );//Receive node from client.
			if( size <= 0 ) {
				if( size < 0 ) {
					perror("Server ");
					return 1;
				}
				done = 1;
			}

			list = addTask( list, node );//Add the node in the list.

			if( !done ) {
				if( send( descServer2, list, sizeof( List ), 0 ) < 0 ) {//Send the list to the client.
					perror("Server ");
					done = 1;
				}
			}

		}while( !done );

		close( descServer2 );
		showTasks( list );//Everiything works fine here!
	}

	return 0;
}

//Client.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include "tasks.h"

#define SOCK_PATH "socket_comm"

int main(void) {
	
	int descServer1, length;
	struct sockaddr_un client;
	List *list = ( List * )malloc( sizeof( List ) );

	if( ( descServer1 = socket( AF_UNIX, SOCK_STREAM, 0 ) ) == -1 ) {
		perror("Client ");
		return 1;
	}

	client.sun_family = AF_UNIX;
	strcpy(client.sun_path, SOCK_PATH);
	length = strlen(client.sun_path) + sizeof(client.sun_family);

	if( connect( descServer1, ( struct sockaddr * )&client, length ) == -1 ) {
		perror("Client ");
		return 1;
	}

	while( 1 ) {
		int size, val;
		printf("Client - You are connected.\n");
		printf("Client - Type a number, please.\n");
		printf("Client - Number: ");
		
		scanf("%d", &val);
		if( val == 99 ) {
			break;
		}

		List *task = createTask( val );
	
		if( send( descServer1, task, sizeof( List ), 0 ) == -1 ) {
			perror("Client ");
			return 1;
		}

		size = recv( descServer1, list, sizeof( List ), 0 );
		if( size <= 0 ) {
			if( size < 0 ) {
				perror("Client ");
				return 1;
			}
			break;
		}

		showTasks( list );//It should show the linked list, but it is giving segmentation fault error.

		//Just testing. He shows the head of the linked list correctly. Hour in head is 888.
		printf("Hora: %d. \n", list->hour );
		//Here, it seems that he lost the address of the rest of the list because i have segmentation fault error.
		printf("Hora: %d. \n", list->prox->hour );
	}
	
	close( descServer1 );

	return 0;

}


Is This A Good Question/Topic? 0
  • +

Replies To: Segmentation fault error in linked lists.

#2 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3663
  • View blog
  • Posts: 11,482
  • Joined: 05-May 12

Re: Segmentation fault error in linked lists.

Posted 06 July 2013 - 05:24 PM

You do realize that unless you are using shared memory between the client and the server that you can't send pointers between processes.
Was This Post Helpful? 1
  • +
  • -

#3 robgeek  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 104
  • Joined: 15-January 13

Re: Segmentation fault error in linked lists.

Posted 06 July 2013 - 06:52 PM

But, why when i send a array int, it works fine? Like:
int myArray[10];
int x = send( descServidor1, &myArray, sizeof( int ), 0 );
//or
int y = recv( descServidor1, &myArray, sizeof( int ), 0 );

I'm sending the address of the first cell, just like my example!

How can i solve this problem?
Was This Post Helpful? 0
  • +
  • -

#4 robgeek  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 104
  • Joined: 15-January 13

Re: Segmentation fault error in linked lists.

Posted 06 July 2013 - 07:00 PM

One more thing. In client code, i'm sending a pointer and, in server, he accepts this pointer and add to the list, and he shows the list correctly. Why is this working fine? And why i can't send back to the client a pointer like i did with server?
Was This Post Helpful? 0
  • +
  • -

#5 #define  Icon User is offline

  • Duke of Err
  • member icon

Reputation: 1432
  • View blog
  • Posts: 4,968
  • Joined: 19-February 09

Re: Segmentation fault error in linked lists.

Posted 06 July 2013 - 08:11 PM

The program works on your computer but the method is not defined/standardised, in the future or on another computer the methods for giving processes access to memory could change.

It is considered safer to send all the data through the socket.


int myArray[10];
int x = send( descServidor1, &myArray, sizeof( myArray ), 0 );
//or
int y = recv( descServidor1, &myArray, sizeof( int ) * 10, 0 );


Was This Post Helpful? 0
  • +
  • -

#6 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3663
  • View blog
  • Posts: 11,482
  • Joined: 05-May 12

Re: Segmentation fault error in linked lists.

Posted 06 July 2013 - 09:56 PM

View Postrobgeek, on 06 July 2013 - 09:52 PM, said:

But, why when i send a array int, it works fine? Like:
int myArray[10];
int x = send( descServidor1, &myArray, sizeof( int ), 0 );
//or
int y = recv( descServidor1, &myArray, sizeof( int ), 0 );

I'm sending the address of the first cell, just like my example!

How can i solve this problem?

You aren't sending the address. What send() did was that it read sizeof(int) bytes starting at &myArray in the server's address space, and sent it over the wire. recv() took those bytes and started writing them into &myArray in the client's address space.

The best way to think of this is if you had a structure like your list node and used fwrite() to save the structure out to a file, and then you quit out of your program. If the structure had prox pointing to the address 0x48e756a8, the value 0x48e756a8 will be written out to file. Next you fire up your favorite game (to force your program to run in a different address space), and then try to use fread() to read the structure back into memory. prox will still continue to be pointing to the address 0x48e756a8 which will more likely than not, not be valid for this run of your program because it is now running in a different address space.
Was This Post Helpful? 0
  • +
  • -

#7 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3663
  • View blog
  • Posts: 11,482
  • Joined: 05-May 12

Re: Segmentation fault error in linked lists.

Posted 06 July 2013 - 10:05 PM

View Postrobgeek, on 06 July 2013 - 10:00 PM, said:

One more thing. In client code, i'm sending a pointer and, in server, he accepts this pointer and add to the list, and he shows the list correctly. Why is this working fine? And why i can't send back to the client a pointer like i did with server?

You haven't shown us the implementation of addTask(), but based on your description here:

View Postrobgeek, on 06 July 2013 - 07:56 PM, said:

The server program receives a node of a linked list and inserts it in a linked list head.

It looks like the implementation of addTask() looks something like this:
List * addTask(List * head, List * node)
{
    node->prox = NULL;
    node->ant = head;
    head->prox = node;
    return node;
}


where the pointers prox and ant in node are completely overwritten.

This post has been edited by Skydiver: 06 July 2013 - 10:05 PM

Was This Post Helpful? 1
  • +
  • -

#8 robgeek  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 104
  • Joined: 15-January 13

Re: Segmentation fault error in linked lists.

Posted 06 July 2013 - 10:48 PM

Here is the implementation of addTask().
She always puts the node in the last position of the list.
List* adicionaTarefa(List *l, List *node) {
	if( l->prox == NULL ) {
		node->ant = l;
		node->prox = NULL;
		l->prox = node;
		node->id = node->ant->id + 1;//Each node receives an id in ascending order.
		return l;
	} 
	else {
		Lista *aux = l->prox;
		while( aux->prox != NULL ) {
			aux = aux->prox;
		}
		node->prox = aux->prox;
		node->ant = aux;
		aux->prox = node;
	}
	node->id = node->ant->id + 1;//Each node receives an id in ascending order.
	return l;
}


What is wrong? Please, guys, i really want to do this using sockets.
Was This Post Helpful? 0
  • +
  • -

#9 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3663
  • View blog
  • Posts: 11,482
  • Joined: 05-May 12

Re: Segmentation fault error in linked lists.

Posted 07 July 2013 - 07:29 AM

Well, that contradicts what you said:

View Postrobgeek, on 06 July 2013 - 07:56 PM, said:

The server program receives a node of a linked list and inserts it in a linked list head.

What is happening is that she is actually inserting the node as the linked lists' tail.

Anyway, it still doesn't matter. If you look closely at the code, she never reads the pointers from the node object that is passed in. She only writes into the pointers. This is why it works for the server. It completely ignores whatever pointer value was sent by the client. The problem is that the client is taking the pointer value passed by the server.
Was This Post Helpful? 1
  • +
  • -

#10 robgeek  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 104
  • Joined: 15-January 13

Re: Segmentation fault error in linked lists.

Posted 07 July 2013 - 07:57 AM

Mmmm...
I really didn't undertand!

Quote

she never reads the pointers from the node object that is passed in.

She, you mean, addTask() in the server code, right? I believe this is happening because addTask() assumes that the node which will be inserted in the list has his both pointers NULL.

Quote

It completely ignores whatever pointer value was sent by the client.

I thought that this information did not matter, because pointers of the node that i send from he cliente are NULL.

Quote

The problem is that the client is taking the pointer value passed by the server.

The client receives the head of the list, and her pointer has the address of the first node that i send from the client! Right?

I tried to make using a array of List and it worked perfectly. But it's a ugly solution.
Was This Post Helpful? 0
  • +
  • -

#11 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3663
  • View blog
  • Posts: 11,482
  • Joined: 05-May 12

Re: Segmentation fault error in linked lists.

Posted 07 July 2013 - 10:33 AM

View Postrobgeek, on 07 July 2013 - 10:57 AM, said:

Quote

The problem is that the client is taking the pointer value passed by the server.

The client receives the head of the list, and her pointer has the address of the first node that i send from the client! Right?

Unfortunately, the client receives the node at the head of the list. The node unfortunately contains pointers that are pointing to memory in the server.
Was This Post Helpful? 0
  • +
  • -

#12 jjl  Icon User is offline

  • Engineer
  • member icon

Reputation: 1112
  • View blog
  • Posts: 4,619
  • Joined: 09-June 09

Re: Segmentation fault error in linked lists.

Posted 07 July 2013 - 10:55 PM

Trying to send a pointer and dereferencing it between processes will cause an access violation. You should understand that each process has it's own page table. All memory locations used in a process are virtual, not hardware address. The virtual addresses are dependent on a virtual page number and memory offset (the offset into the memory page). Not only will trying to dereference memory allocated in another cause an access allocation, the virtual -> physical address translation will result in different addresses for both processes.

This post has been edited by jjl: 07 July 2013 - 10:56 PM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1