title: malloc() is returning the same address multiple times, even when I haven't used free()
body: <p>EDIT: I did use free(), ignore the title. </p>
  
  <p>The gist is that every time <code>malloc()</code> is called, the address <strong>0x8403620</strong>
  is returned, which I found out using Gdb. </p>
  
  <pre><code>tellers[i] = create_teller(0, i, NULL);
  </code></pre>
  
  <p>I first use <code>malloc()</code> on line 72 to create 3 teller structures. The first addressed returned, visible through Gdb, is <strong>0x84003620</strong>. The second is
  <strong>0x84033a0</strong>, the third <strong>0x84034e0</strong>. Everything seems fine.</p>
  
  <pre><code>clients[i] = create_client(0, i, -1, -1);
  </code></pre>
  
  <p>Then I use <code>malloc()</code> on line 77 with the <code>create_client(</code>) function to 
  create 100 clients. The first address, assigned to client[0], is ...
  <strong>0x8403620</strong>. The same as tellers[0]. It gets worse. The next address
  returned from <code>malloc()</code> is <strong>0x8403620</strong> again for when i = 1, and so 
  on for i = 3, 4, ..., 99. </p>
  
  <p>It isn't inherently the <code>create_client()</code> or the <code>create_teller()</code> functions, but
  instead the <code>malloc()</code> function itself. </p>
  
  <p>This is simply a very odd situation. </p>
  
  <p><strong><em>Now, I'd like to ask</em></strong>: Am I using <code>malloc()</code> wrong? Or is my version of <code>malloc()</code> bugged and should I somehow reinstall whatever it is? It's most likely my code since it works for creating the tellers, just not for the clients.</p>
  
  <p>Here is the full code:</p>
  
  <pre class="lang-c prettyprint-override"><code>#include &lt;pthread.h&gt;
  #include &lt;semaphore.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;stdbool.h&gt;
  #include &lt;time.h&gt;
  #include &lt;assert.h&gt;
  
  
  typedef struct teller teller_t;
  typedef struct client client_t;
  
  teller_t *  create_teller (pthread_t thread_id, int id, client_t *assigned_client);
  client_t *  create_client (pthread_t thread_id, int id, int operation, int amount);
  void *      run_teller (void *arg);
  void *      run_client (void *arg);
  
  /* types of operations */
  #define DEPOSIT     0
  #define WITHDRAW    1
  
  #define NUM_TELLERS 3
  #define NUM_CLIENTS 100
  
  struct client {
      pthread_t thread_id;
  
      int id;
      int operation;
      int amount;
  };
  
  struct teller {
      pthread_t thread_id;
  
      int id;
      bool available;
      client_t *assigned_client;
  };
  
  client_t *clients[100];
  teller_t *tellers[3];
  
  /* only 2 tellers at a time can access */
  sem_t safe;
  /* only 1 teller at a time can access */
  sem_t manager;
  /* amount of tellers available, at most 3 */
  sem_t line; /* rename to available? */
  /* each teller waiting for a client to be assigned to them */
  sem_t wait_for_client[3];
  
  
  int
  main (int argc, char **argv) {
      (void) argc; 
      (void) argv;
  
      srand(time(NULL));
  
      /* This also tells us how many clients have been served */
      int client_index = 0;
  
      sem_init(&amp;safe, 0, 2);
      sem_init(&amp;manager, 0, 1);
      sem_init(&amp;line, 0, 0);
      for (int i = 0; i &lt; 3; i++) 
          sem_init(&amp;wait_for_client[i], 0, 0);
  
      for (int i = 0; i &lt; NUM_TELLERS; i++) {
          tellers[i] = create_teller(0, i, NULL);
          pthread_create(&amp;tellers[i]-&gt;thread_id, NULL, run_teller, (void *) tellers[i]);
      }
  
      for (int i = 0; i &lt; NUM_CLIENTS; i++) {
          clients[i] = create_client(0, i, -1, -1);
          pthread_create(&amp;clients[i]-&gt;thread_id, NULL, run_client, (void *) clients[i]);
      }
  
      /* DEBUG
      for (int i = 0; i &lt; NUM_CLIENTS; i++) {
          printf("client %d has id %d\n", i, clients[i]-&gt;id);
      }
      */
  
      // No threads should get past this point!!!
      // ==------------------------------------==
  
      // Should all of this below be handled by the clients instead of main?
  
      while (1) {
          if (client_index &gt;= NUM_CLIENTS) {
              // TODO:
              // tell tellers that there are no more clients 
              // so they should close, then then close the bank.
  
              break;
          }
  
          sem_wait(&amp;line);
  
          for (int i = 0; i &lt; 3; i++) {
              if (tellers[i]-&gt;available) {
                  int client_id = clients[client_index]-&gt;id;
  
                  //printf("client_index = %d\n", client_index); // DEBUG
  
                  tellers[i]-&gt;assigned_client = clients[client_index++];
                  tellers[i]-&gt;available = false;
  
  
                  printf(
                      "Client %d goes to Teller %d\n", 
                      client_id, 
                      tellers[i]-&gt;id
                  );
  
                  sem_post(&amp;wait_for_client[i]);
  
                  break;
              }
          }
  
          //sem_post(&amp;line); // Is this needed?
      }
  
      return EXIT_SUCCESS;
  }
  
  
  teller_t *  
  create_teller (pthread_t thread_id, int id, client_t *assigned_client) {
      teller_t *t = (teller_t *) malloc(sizeof(teller_t));
      if (t == NULL) {
          printf("ERROR: Unable to allocate teller_t.\n");
          exit(EXIT_FAILURE);
      }
  
      t-&gt;thread_id = thread_id;
      t-&gt;id = id;
      t-&gt;available = true;
      t-&gt;assigned_client = assigned_client;
  
      return t;
  }
  
  /* TODO: Malloc returns the same address everytime, fix this */
  client_t *  
  create_client (pthread_t thread_id, int id, int operation, int amount) {
      client_t *c = malloc(sizeof(client_t));
  
      if (c == NULL) {
          printf("ERROR: Unable to allocate client_t.\n");
          exit(EXIT_FAILURE);
      }
  
      c-&gt;thread_id = thread_id;
      c-&gt;id = id;
      c-&gt;operation = operation;
      c-&gt;amount = amount;
  
      return c;
  }
  
  
  void *
  run_teller (void *arg) {
      teller_t *t = (teller_t *) arg;
  
      printf("Teller %d is available\n", t-&gt;id);
  
      while (1) {
          /* tell the line that a teller is available */
          sem_post(&amp;line); 
          /* pass when the line assignes a client to this teller */
          sem_wait(&amp;wait_for_client[t-&gt;id]); 
  
          assert(t-&gt;assigned_client != NULL);
  
          if (t-&gt;assigned_client-&gt;operation == WITHDRAW) {
  
          }
          else {
  
          }
      }
  
      free(arg);
  
      pthread_cancel(t-&gt;thread_id);
      return NULL;
  }
  
  
  void *
  run_client (void *arg) {
      client_t *c = (client_t *) arg;
  
      c-&gt;operation = rand() &amp; 1;
  
      printf(
          "Client %d waits in line to make a %s\n", 
          c-&gt;id, 
          ((c-&gt;operation == DEPOSIT) ? "Deposit" : "Withdraw")
      );
  
      free(arg);
  
      pthread_cancel(c-&gt;thread_id);
      return NULL;
  }
  </code></pre>