This source, mpi_vg_demo2.c (with line numbers), is for a pathologically bad MPI program used in the Valgrind Memcheck tool documentation found here.

01:/* Demonstrate some of Valgrind's ability to find memory errors and leaks */
02:/* Compile with 'mpiicc -g mpi_vg_demo2.c -o mpi_vg_demo2' */
03:#include "mpi.h"
04:#include <stdio.h>
05:#include <stdlib.h>
06:
07:int main(int argc, char *argv[])
08:{
09:    int numtasks, rank, rc, i, *null_ptr;
10:    char *buf, ch1;
11:    MPI_Status status;
12:    MPI_Request request;
13:    int sum, sum2;
14:    char *send_buf, *recv_buf;
15:    int send_to, recv_from;
16:    
17:    rc = MPI_Init(&argc,&argv);
18:    if (rc != MPI_SUCCESS) {
19:        printf ("Error starting MPI program. Terminating.\n");
20:        MPI_Abort(MPI_COMM_WORLD, rc);
21:    }
22:    
23:    MPI_Comm_size(MPI_COMM_WORLD,&numtasks);
24:    MPI_Comm_rank(MPI_COMM_WORLD,&rank);
25:    
26:    /* Send and recv data from someone else if possible */
27:    send_to = rank + 1;
28:    if (send_to >= numtasks)
29:        send_to -= numtasks;
30:    recv_from = rank - 1;
31:    if (recv_from < 0)
32:        recv_from += numtasks;
33:    
34:    printf ("Number of tasks= %d My rank= %d Send to %d Recv from %d\n",
35:            numtasks,rank, send_to, recv_from);
36:    
37:    /* Demonstrate some Memcheck features */
38:    buf = (char *) malloc (100);
39:    
40:    ch1 = buf[2]; /* Uninitialized memory read */
41:    
42:    buf[100] = 0; /* Write past malloced size */
43:    
44:    ch1 = buf[100]; /* Read past malloced size */
45:    
46:    buf = (char*) malloc (200); /* Lose pointer to original buffer */
47:    
48:    free (buf);
49:    
50:    char *freed_buf = buf;
51:    
52:    /* Not freed but pointer exists, so Memcheck doesn't report as leak */
53:    buf = (char *) malloc (40);
54:    
55:    /* Allocate buffers for MPI test */
56:    send_buf = (char *)malloc (20);
57:    
58:    /* Initialize only the first 15 characters */
59:    for (i=0; i < 15; i++)
60:       send_buf[i] = i;
61:    
62:    recv_buf = (char *)malloc (30);
63:    
64:    free (freed_buf); /* Free twice */
65:    
66:    /* Send more data than allocated, shows as BFCP inside MPI_ISend */
67:    /* Wrappers should also detect unitialized use also */
68:    MPI_Isend (send_buf, 25, MPI_CHAR, send_to, 0, MPI_COMM_WORLD,
69:               &request);
70:    
71:    /* Receive data sent above into bigger buffer */
72:    MPI_Recv (recv_buf, 30, MPI_CHAR, recv_from, 0, MPI_COMM_WORLD, &status);
73:    
74:    /* Free up Send's request */
75:    MPI_Wait (&request, &status);
76:    
77:    /* Sum data that was actually initialized and sent */
78:    sum = 0;
79:    for (i=0; i < 15; i++)
80:        sum += recv_buf[i];
81:    
82:    /* Valgrind should not complain here with MPI wrappers */
83:    printf ("Sum over initialized data for rank %i is %i\n", rank, sum);
84:    
85:    /* Sum more data than was actually received */
86:    sum2 = 0;
87:    for (i=0; i < 30; i++)
88:        sum2 += recv_buf[i]; /* Last 5 bytes uninitialized */
89:    
90:    /* Valgrind should compain here, even with MPI wrappers */
91:    printf ("Sum over uninitialized data for rank %i is %i\n", rank, sum2);
92:    
93:    free (&rank); /* Free of unallocated memory */
94:    
95:    MPI_Finalize();
96:}