SailorCire
SailorCire

Reputation: 568

Segmentation Fault with C++ class network programming

I'm trying to write a c++ program that uses classes, starts and listens for network connections, and then spins off a new thread for each new client.

Fortunately, I've figured out how to spawn a thread from inside a class, but when trying to do a accept() in the class I get a segmentation fault. I'll post the code to make it a little easier to show where I'm having issues.

#include <iostream>
#include <string.h> //for memset
#include <pthread>
#include <sys/types.h> //network
#include <sys/socket.h> //network
#include <netinet/in.h> //network

using namespace std;
class network
{
  public:
    void my_listen();
    static void *handleClient(void * in_stream);
};

void* network::handleClient(void * in_stream)
{

  int *stream = reinterpret_cast<int *>(in_stream);
  write(*stream,"Hello Client\n", 12);
}

void network::my_listen()
{
  /*
   * Name: my_listen()
   * Purpose: Listens and accepts new connections. Once accpeted, a new thread
   *          is spun off. 
   * Input: none
   * Output: none
  */

  int *new_socket_desc;
  int port_num = 9876;
  socklen_t client_addr_len;

  int socket_desc = socket(AF_INET,SOCK_STREAM,0);

  sockaddr_in serv_addr, cli_addr;

  if(socket_desc == -1)
  {
    cerr << "Unable to create new sockets\n";
  }

  memset(&serv_addr, 0, sizeof(serv_addr));

  serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = INADDR_ANY;
  serv_addr.sin_port = htons(port_num);

  if(bind(socket_desc, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
  {
    cerr << "Error on binding " << port_num << endl;
  }

  listen(socket_desc,5);

  client_addr_len = sizeof(cli_addr);

  pthread_t thread[10];
  int count = 0;

  *new_socket_desc = accept(socket_desc, (struct sockaddr *) &cli_addr, &client_addr_len); //Right here I segment fault

  cout << "Connected client " << " @ " << new_socket_desc << " (" << *new_socket_desc << ")" <<  endl;

  pthread_create(thread[0], handleClient, (void *)new_socket_desc);

  pthread_join(thread[0],NULL);
}

Main isn't that exciting:

#include "network.h"
using namespace std;

int main()
{
  network my_network;

  my_network.my_listen();
}

What is interesting is that I can get all of this to work without using a class. I'm sure it has something to do with scope, but I don't know why.

By the way, I'm using gcc 4.6.2 with a target platform of x86_64

Upvotes: 1

Views: 397

Answers (2)

Galimov Albert
Galimov Albert

Reputation: 7357

int *new_socket_desc;
// ....
*new_socket_desc = accept(socket_desc ....

You declaring new_socket_desc as a unitialized pointer, then assigning result of accept to random memory location pointed by new_socket_desc. So obviously this causes SEGFAULT. You should do:

int new_socket_desc;
// ....
new_socket_desc = accept(socket_desc ....

Upvotes: 1

antlersoft
antlersoft

Reputation: 14786

You declare new_socket_desc as a pointer but never set what it is pointing to. When you try to put a value at the location of the pointer (with the result of your accept call) it is writing to some random location in memory, which may or may not cause an immediate crash (in this version of your code it is causing a crash) but is always very bad.

Make new_socket_desc a regular int member of your class, use the & operator on it when creating the thread, and don't use the * operator on it otherwise, and you should have better luck.

Upvotes: 2

Related Questions