C++ Allocating Dynamic Multidimentional Arrays

Aim
To demonstrate dynamic array allocation in C++. Dynamic array allocation in C++ can take many forms. Regardless of whether you use malloc or new, you have to be carefull when freeing up memory using free or delete. In these examples we will allocate three dimentional 3D arrays as it give a better insight than two dimentional 2D arrays. The examples are given below.

int***p Dynamic using malloc
int***p Dynamic using new
int (*p)[10][10] Sem-Dynamic using new.

Now let us look at these in more detail below.

Dynamic Malloc
The first way to allocate an array is using malloc and a pointer to a pointer to a pointer. You have to free all the arrays at the end Malloc doesn't call constuctors and free doesn't call destructors.
 1. #include <stdlib.h>
 2. #include <stdio.h>
 3. 
 4. int main(){
 5. 
 6.     int*** p;
 7. 
 8.     int x    = 10;
 9.     int y    = 10;
10.     int z     = 10;
11. 
12.     int i, j;
13. 
14.     p = (int***)malloc(x*sizeof(int**));
15. 
16.     for(i=0; i < x; i++){
17.         p[i] = (int**)malloc(y*sizeof(int*));
18.         for(j=0; j < y; j++){
19.             p[i][j] = (int*)malloc(z*sizeof(int));
20.         }
21.     }
22. 
23.     p[0][2][3]=100;
24.     p[4][5][4]=101;
25.     printf("values %d\n", p[0][2][3]);
26.     
27.     for(i=0; i < x ; i++){
28.         for(i=0; i < y ; i++){
29.             free(p[i][j]);
30.         }
31.         free (p[i]);
32.     }
33.     free (p);
34. }
Hide line numbers

Dynamic New
Now let us look at dynamically allocating an array using the new operator. You have to delete all the arrays after you have finished.
 1. #include <stdlib.h>
 2. #include <stdio.h>
 3. 
 4. int main(){
 5. 
 6.     int x = 10;
 7.     int y = 10;
 8.     int z = 10;
 9. 
10.     int i, j;
11. 
12.     int ***p; 
13.     
14.     p =  new int**[x];
15. 
16.     for(i=0; i<x; i++){
17.         p[i] = new int*[y];
18.         for(j=0; j<x; j++){
19.             p[i][j] = new int[z];
20.         }
21.     }
22. 
23.     p[1][2][3]=100;
24.     p[4][5][6]=100;
25.     printf("values %d\n", p[1][2][3]);
26. 
27.     for(i=0; i<x; i++){
28.         for(j=0; j<x; j++){
29.             delete [] p[i][j];
30.         }
31.         delete  [] p[i] ;
32.     }
33.     delete [] p;
34. }
Hide line numbers

Semi-Dynamic with 'new'
Next let us have a look at semi-dynamically allocating an array using 'new'. It's semi dynamic because you can vary only one array length and the others are fixed. p is basicall a pointer to a multidimentional array of int.
 1. #include <stdlib.h>
 2. #include <stdio.h>
 3. 
 4. int main(){
 5. 
 6.     int x = 10;
 7.     const int y(10);
 8.     const int z(10);
 9. 
10.     int i, j;
11. 
12.     int (*p)[y][z] = new int[x][y][z];
13.     
14.     p[0][2][3]=100;
15.     p[4][5][4]=101;
16.     printf("values %d\n", p[0][2][3]);
17. 
18.     delete [] p    ;
19. }
Hide line numbers

Linux C++ Forking Server and Client Socket Example

Aim
The goal of this example is to create simple Linux C++ server that accepts socket connections and forks-off to handle the connection. This is the simplest Linux C++ forking server socket and client example you can find. This covers all the steps required to open a C++ clinet/server socket and forking a process. Please leave any comments or questions at the end of this tutorial and I will endeavour to answer them. This tutorial shares the client code with Linux C++ Socket Example with Client Server and Mulit-Threading .

Assumptions
This article assumes that you have a Linux based C++ compiler installed and configured. You can use cygwin if you do not have a Linux environment.

Versions used in this example
Sofware/ComponentImage
Fedora Core 5N/A
Links to these files can be found here

You can download the zipped example here.

Steps required for a server socket
  1. Initialize the socket using socket().
  2. Set any options such as blocking etc using setsockopt().
  3. Bind to the local address and port using bind(). For a server use INADDR_ANY as the address.
  4. listen() for connections.
  5. Go into a loop and accept connections usin accept().
  6. fork! handle the connection in the child process and go back to listening for another socket in the parent process
  7. Read and write to the socket. within the thread.
  8. close()
  9. When you are done, close the server socket using close()

Steps required for a client socket
    Please see the Linux C++ Socket Example with Client Server and Mulit-Threading tutorial for the client.

Write and compile the Server
  1. The server listens on port 1101 for a connection. When it receives a connection it creates a thread via pthread_create to handle it. This thread then reads from the socket, appends " SERVER ECHO" to it and sends it back to the client. As the server doesn't require an IP address, we assign INADDR_ANY to the sockaddr_in struct. Save this code as LinSever.cpp.
     1. #include <fcntl.h>
     2. #include <string.h>
     3. #include <stdlib.h>
     4. #include <errno.h>
     5. #include <stdio.h>
     6. #include <netinet/in.h>
     7. #include <resolv.h>
     8. #include <sys/socket.h>
     9. #include <arpa/inet.h>
    10. #include <unistd.h>
    11. #include <pthread.h>
    12. 
    13. void* SocketHandler(void*);
    14. 
    15. int main(int argv, char** argc){
    16. 
    17.     int host_port= 1101;
    18. 
    19.     struct sockaddr_in my_addr;
    20. 
    21.     int hsock;
    22.     int * p_int ;
    23.     int err;
    24. 
    25.     socklen_t addr_size = 0;
    26.     int* csock;
    27.     sockaddr_in sadr;
    28.     pthread_t thread_id=0;
    29. 
    30.     int childpid;
    31. 
    32.     signal(SIGCHLD, SIG_IGN);
    33. 
    34.     hsock = socket(AF_INET, SOCK_STREAM, 0);
    35.     if(hsock == -1){
    36.         printf("Error initializing socket %d\n", errno);
    37.         goto FINISH;
    38.     }
    39.     
    40.     p_int = (int*)malloc(sizeof(int));
    41.     *p_int = 1;
    42.         
    43.     if( (setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char*)p_int, sizeof(int)) == -1 )||
    44.         (setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE, (char*)p_int, sizeof(int)) == -1 ) ){
    45.         printf("Error setting options %d\n", errno);
    46.         free(p_int);
    47.         goto FINISH;
    48.     }
    49.     free(p_int);
    50. 
    51. 
    52.     my_addr.sin_family = AF_INET ;
    53.     my_addr.sin_port = htons(host_port);
    54.     
    55.     memset(&(my_addr.sin_zero), 0, 8);
    56.     my_addr.sin_addr.s_addr = INADDR_ANY ;
    57.     
    58.     if( bind( hsock, (sockaddr*)&my_addr, sizeof(my_addr)) == -1 ){
    59.         fprintf(stderr,"Error binding to socket, make sure nothing else is listening on this port %d\n",errno);
    60.         goto FINISH;
    61.     }
    62.     if(listen( hsock, 10) == -1 ){
    63.         fprintf(stderr, "Error listening %d\n",errno);
    64.         goto FINISH;
    65.     }
    66. 
    67.     //Now lets do the server stuff
    68. 
    69.     addr_size = sizeof(sockaddr_in);
    70.     
    71.     while(true){
    72.         printf("waiting for a connection\n");
    73.         csock = (int*)malloc(sizeof(int));
    74.         if((*csock = accept( hsock, (sockaddr*)&sadr, &addr_size))!= -1){
    75.             printf("---------------------\nReceived connection from %s\n",inet_ntoa(sadr.sin_addr));
    76.             switch( childpid=fork()){
    77.                 case -1://error
    78.                     fprintf(stderr, "Error spawning the child %d\n",errno);
    79.                     exit(0);
    80.                     break;
    81.                 case 0://in the child
    82.                     SocketHandler(csock);
    83.                     exit(0);
    84.                 default://in the server
    85.                     close(*csock);
    86.                     free(csock);
    87.                     break;
    88.             }
    89.         }
    90.         else{
    91.             fprintf(stderr, "Error accepting %d\n", errno);
    92.         }
    93.     }
    94.     
    95. FINISH:
    96. ;
    97. }
    98. 
    99. void* SocketHandler(void* lp){
    100.     int *csock = (int*)lp;
    101. 
    102.     char buffer[1024];
    103.     int buffer_len = 1024;
    104.     int bytecount;
    105. 
    106.     memset(buffer, 0, buffer_len);
    107.     if((bytecount = recv(*csock, buffer, buffer_len, 0))== -1){
    108.         fprintf(stderr, "Error receiving data %d\n", errno);
    109.         goto FINISH;
    110.     }
    111.     printf("Received bytes %d\nReceived string \"%s\"\n", bytecount, buffer);
    112.     strcat(buffer, " SERVER ECHO");
    113. 
    114.     if((bytecount = send(*csock, buffer, strlen(buffer), 0))== -1){
    115.         fprintf(stderr, "Error sending data %d\n", errno);
    116.         goto FINISH;
    117.     }
    118.     
    119.     printf("Sent bytes %d\n", bytecount);
    120. 
    121. 
    122. FINISH:
    123.     free(csock);
    124.     return 0;
    125. }
    Hide line numbers

    Line 32: When a child process exits without a call to 'wait()' from the parent, it turns into a 'zombie.' You can prevent this by setting signal(SIGCHLD, SIG_IGN);

    Line 76: Fork returns -1 in the parent on failure. It return the child pid in the parent and 0 in the child.

    Line 85: When you fork, you must close the client connection in the parent(server) process, otherwise you will hit the "open socket descriptor limit" in Linux.
  2. `
  3. Open a prompt to the working directory and compile the code using your C++ compiler

    ..workspace\SocketExample>g++ -o server LinServer.cpp -lpthread

Write and compile the Client
  1. The client reads a line from the console and sends this to the server. It then reads from the server and displays it on the console. You can view the client in this tutorial Linux C++ Socket Example with Client Server and Mulit-Threading .


Run the example
  1. Open a prompt to the working directory and run the server.

    ..workspace\SocketExample>server

  2. Open another prompt to the working directory and run the Client.

    ..workspace\SocketExample>client

  3. Now type something into the client prompt and press ENTER.
  4. You will see the exchange between client and server. You can open many client prompts at the same time and test.

Linux C++ Socket Example with Client Server and Mulit-Threading

Aim
The aim of this Linux C++ example is to create simple client/server socket communication and multi-threading program on Linux. This shows the basics such as binding, listening and accepting sockets for Servers and connecting sockets for clients. Once the server accepts a socket, a thread is spawned to handle it. The threads are C++ POSIX threads. This is the simplest Linux C++ multi-threaded socket example you can find. Please leave any comments or questions at the end of this tutorial and I will endeavour to answer them. For a forking server look at Linux C++ Forking Server and Client Example.

Assumptions
This article assumes that you have a Linux based C++ compiler installed and configured. You can use cygwin if you do not have a Linux environment.

Versions used in this example
Sofware/ComponentImage
Fedora Core 5N/A
Links to these files can be found here

You can download the zipped example here.

Steps required for a server socket
  1. Initialize the socket using socket().
  2. Set any options such as blocking etc using setsockopt().
  3. Bind to the local address and port using bind(). For a server use INADDR_ANY as the address.
  4. listen() for connections.
  5. Go into a loop and accept connections usin accept(). Spawn threads (pthread_create) to handle these connections, so you can accept more connections.
    • Read and write to the socket. within the thread.
    • close()
    • When you are done, close the server socket using close()

    Steps required for a client socket
    1. Initialize the socket using socket().
    2. Set any options such as blocking etc using setsockopt().
    3. Connect to the remote host using connet(). Supply address and port here.
    4. Read and write to the socket. close()

    Write and compile the Server
    1. The server listens on port 1101 for a connection. When it receives a connection it creates a thread via pthread_create to handle it. This thread then reads from the socket, appends " SERVER ECHO" to it and sends it back to the client. As the server doesn't require an IP address, we assign INADDR_ANY to the sockaddr_in struct. Save this code as LinSever.cpp.
       1. #include <fcntl.h>
       2. #include <string.h>
       3. #include <stdlib.h>
       4. #include <errno.h>
       5. #include <stdio.h>
       6. #include <netinet/in.h>
       7. #include <resolv.h>
       8. #include <sys/socket.h>
       9. #include <arpa/inet.h>
      10. #include <unistd.h>
      11. #include <pthread.h>
      12. 
      13. void* SocketHandler(void*);
      14. 
      15. int main(int argv, char** argc){
      16. 
      17.     int host_port= 1101;
      18. 
      19.     struct sockaddr_in my_addr;
      20. 
      21.     int hsock;
      22.     int * p_int ;
      23.     int err;
      24. 
      25.     socklen_t addr_size = 0;
      26.     int* csock;
      27.     sockaddr_in sadr;
      28.     pthread_t thread_id=0;
      29. 
      30. 
      31.     hsock = socket(AF_INET, SOCK_STREAM, 0);
      32.     if(hsock == -1){
      33.         printf("Error initializing socket %d\n", errno);
      34.         goto FINISH;
      35.     }
      36.     
      37.     p_int = (int*)malloc(sizeof(int));
      38.     *p_int = 1;
      39.         
      40.     if( (setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char*)p_int, sizeof(int)) == -1 )||
      41.         (setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE, (char*)p_int, sizeof(int)) == -1 ) ){
      42.         printf("Error setting options %d\n", errno);
      43.         free(p_int);
      44.         goto FINISH;
      45.     }
      46.     free(p_int);
      47. 
      48.     my_addr.sin_family = AF_INET ;
      49.     my_addr.sin_port = htons(host_port);
      50.     
      51.     memset(&(my_addr.sin_zero), 0, 8);
      52.     my_addr.sin_addr.s_addr = INADDR_ANY ;
      53.     
      54.     if( bind( hsock, (sockaddr*)&my_addr, sizeof(my_addr)) == -1 ){
      55.         fprintf(stderr,"Error binding to socket, make sure nothing else is listening on this port %d\n",errno);
      56.         goto FINISH;
      57.     }
      58.     if(listen( hsock, 10) == -1 ){
      59.         fprintf(stderr, "Error listening %d\n",errno);
      60.         goto FINISH;
      61.     }
      62. 
      63.     //Now lets do the server stuff
      64. 
      65.     addr_size = sizeof(sockaddr_in);
      66.     
      67.     while(true){
      68.         printf("waiting for a connection\n");
      69.         csock = (int*)malloc(sizeof(int));
      70.         if((*csock = accept( hsock, (sockaddr*)&sadr, &addr_size))!= -1){
      71.             printf("---------------------\nReceived connection from %s\n",inet_ntoa(sadr.sin_addr));
      72.             pthread_create(&thread_id,0,&SocketHandler, (void*)csock );
      73.             pthread_detach(thread_id);
      74.         }
      75.         else{
      76.             fprintf(stderr, "Error accepting %d\n", errno);
      77.         }
      78.     }
      79.     
      80. FINISH:
      81. ;
      82. }
      83. 
      84. void* SocketHandler(void* lp){
      85.     int *csock = (int*)lp;
      86. 
      87.     char buffer[1024];
      88.     int buffer_len = 1024;
      89.     int bytecount;
      90. 
      91.     memset(buffer, 0, buffer_len);
      92.     if((bytecount = recv(*csock, buffer, buffer_len, 0))== -1){
      93.         fprintf(stderr, "Error receiving data %d\n", errno);
      94.         goto FINISH;
      95.     }
      96.     printf("Received bytes %d\nReceived string \"%s\"\n", bytecount, buffer);
      97.     strcat(buffer, " SERVER ECHO");
      98. 
      99.     if((bytecount = send(*csock, buffer, strlen(buffer), 0))== -1){
      100.         fprintf(stderr, "Error sending data %d\n", errno);
      101.         goto FINISH;
      102.     }
      103.     
      104.     printf("Sent bytes %d\n", bytecount);
      105. 
      106. 
      107. FINISH:
      108.     free(csock);
      109.     return 0;
      110. }
      Hide line numbers

    2. Open a prompt to the working directory and compile the code using your C++ compiler

      ..workspace\SocketExample>g++ -o server LinServer.cpp -lpthread

    Write and compile the Client
    1. The client reads a line from the console and sends this to the server. It then reads from the server and displays it on the console. Save this code as LinClient.cpp.
       1. #include <fcntl.h>
       2. #include <string.h>
       3. #include <stdlib.h>
       4. #include <errno.h>
       5. #include <stdio.h>
       6. #include <netinet/in.h>
       7. #include <resolv.h>
       8. #include <sys/socket.h>
       9. #include <arpa/inet.h>
      10. #include <unistd.h>
      11. 
      12. int main(int argv, char** argc){
      13. 
      14.     int host_port= 1101;
      15.     char* host_name="127.0.0.1";
      16. 
      17.     struct sockaddr_in my_addr;
      18. 
      19.     char buffer[1024];
      20.     int bytecount;
      21.     int buffer_len=0;
      22. 
      23.     int hsock;
      24.     int * p_int;
      25.     int err;
      26. 
      27.     hsock = socket(AF_INET, SOCK_STREAM, 0);
      28.     if(hsock == -1){
      29.         printf("Error initializing socket %d\n",errno);
      30.         goto FINISH;
      31.     }
      32.     
      33.     p_int = (int*)malloc(sizeof(int));
      34.     *p_int = 1;
      35.         
      36.     if( (setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char*)p_int, sizeof(int)) == -1 )||
      37.         (setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE, (char*)p_int, sizeof(int)) == -1 ) ){
      38.         printf("Error setting options %d\n",errno);
      39.         free(p_int);
      40.         goto FINISH;
      41.     }
      42.     free(p_int);
      43. 
      44.     my_addr.sin_family = AF_INET ;
      45.     my_addr.sin_port = htons(host_port);
      46.     
      47.     memset(&(my_addr.sin_zero), 0, 8);
      48.     my_addr.sin_addr.s_addr = inet_addr(host_name);
      49. 
      50.     if( connect( hsock, (struct sockaddr*)&my_addr, sizeof(my_addr)) == -1 ){
      51.         if((err = errno) != EINPROGRESS){
      52.             fprintf(stderr, "Error connecting socket %d\n", errno);
      53.             goto FINISH;
      54.         }
      55.     }
      56. 
      57.     //Now lets do the client related stuff
      58. 
      59.     buffer_len = 1024;
      60. 
      61.     memset(buffer, '\0', buffer_len);
      62. 
      63.     printf("Enter some text to send to the server (press enter)\n");
      64.     fgets(buffer, 1024, stdin);
      65.     buffer[strlen(buffer)-1]='\0';
      66.     
      67.     if( (bytecount=send(hsock, buffer, strlen(buffer),0))== -1){
      68.         fprintf(stderr, "Error sending data %d\n", errno);
      69.         goto FINISH;
      70.     }
      71.     printf("Sent bytes %d\n", bytecount);
      72. 
      73.     if((bytecount = recv(hsock, buffer, buffer_len, 0))== -1){
      74.         fprintf(stderr, "Error receiving data %d\n", errno);
      75.         goto FINISH;
      76.     }
      77.     printf("Recieved bytes %d\nReceived string \"%s\"\n", bytecount, buffer);
      78. 
      79.     close(hsock);
      80.     
      81. FINISH:
      82. ;
      83. }
      Hide line numbers

    2. Open a prompt to the working directory and compile the code using your C++ compiler

      ..workspace\SocketExample>g++ -o client LinClient.cpp


    Run the example
    1. Open a prompt to the working directory and run the server.

      ..workspace\SocketExample>server

    2. Open another prompt to the working directory and run the Client.

      ..workspace\SocketExample>client

    3. Now type something into the client prompt and press ENTER.
    4. You will see the exchange between client and server. You can open many client prompts at the same time and test.