title: Issues with C in realloc() or free() or double free or corruption
body: <p>I am trying to capture audio packets of variable size, strip the RTP header, then concatenate the audio data to 20 bytes each.  My goal is to create something like a queue and just use pointer arithmetic to chop up data before I copy 20 bytes to a  buffer. The issue occurs when I get a large amount of audio bytes coming into the queue(probably greater than 20). Here is the while loop that captures, copies to queue, and chops up the data:</p>
  
  <pre><code>run_flag = TRUE;
      unsigned char *qs_ptr = NULL;  //the very start of the queue   
      unsigned char *qcur_ptr = NULL;       //the start of current audio packet
      unsigned char *qsa_ptr = NULL;   //the start of new incoming audio data 
      unsigned char *tmp_ptr = NULL; //points to the start of next audio packet to send
      unsigned char audio_buf[20];
      unsigned char buf[MAX_PACKET_LEN];
      unsigned char *pkt_no_hdr = NULL;
      int num_audio_bytes;
      int tot_bytes;
      int num_in_q;
      /* listen for voip packets */
      /* collection */
  
      /* keeps track of audio bytes, send data when = 20 */
      pf=fopen("rtp.dat","w");
      while (run_flag==TRUE) {
              if ((num_bytes = read(fd, buf, MAX_PACKET_LEN)) &lt; 0) {
                      perror("recv");
                      close(sd);
                      exit(1);
              }
              pkt_no_hdr = (unsigned char *)calloc(num_bytes-12, sizeof(unsigned char));
              /* remove 12 rtp header bytes */
              num_audio_bytes = rem_rtp_hdr(pkt_no_hdr, &amp;buf, num_bytes);
              print_bytes(pkt_no_hdr, num_bytes-12);
              printf("num audio bytes: %d\n", num_bytes-12);
              tot_bytes+=num_audio_bytes;
              num_in_q+=num_audio_bytes;
              printf("num_in_q: %d\n", num_in_q);
              cpy_to_q(&amp;qs_ptr, &amp;qcur_ptr, &amp;qsa_ptr, pkt_no_hdr, num_audio_bytes, tot_bytes);
              free(pkt_no_hdr);
              if(num_in_q &gt;= 20) {
                      tmp_ptr = qcur_ptr + 20;
                      memcpy(audio_buf, qcur_ptr, 20);
                      qcur_ptr = tmp_ptr;
                      print_bytes(audio_buf, 20);
                      // add header
                      // send mcast packet
                      num_in_q -= 20;
              }
      }
  </code></pre>
  
  <p>Here's the cpy_to_q function:</p>
  
  <pre><code>void cpy_to_q(unsigned char **qs_ptr, unsigned char **qcur_ptr, unsigned char **qsa_ptr, unsigned char *data, int num_bytes, int tot_bytes) {
      if(*qs_ptr == NULL) {
              *qs_ptr = (unsigned char *)malloc(num_bytes*sizeof(unsigned char) + 1);
              *qcur_ptr = *qs_ptr;
              *qsa_ptr = *qs_ptr;
              memcpy(*qs_ptr, data, num_bytes);
      } else {
              *qs_ptr = (unsigned char *)realloc(*qs_ptr, tot_bytes*sizeof(unsigned char) + 1);
              printf("size of q: %d\n", tot_bytes);
              *qsa_ptr += num_bytes;
              memcpy(*qsa_ptr, data, num_bytes);
      }
  </code></pre>
  
  <p>}</p>
  
  <p>I keep getting errors related to <code>realloc()</code> or <code>free()</code> which must happen in the cpy_to_q function:</p>
  
  <pre><code> \*** glibc detected \*** ./voipBridge: free(): invalid next size (fast):        0x000000000213b5b0 \***
  </code></pre>
  
  <p>Here is what valgrind says when the issue occurs:</p>
  
  <pre><code>Thread 1: status = VgTs_Runnable
  ==3799==    at 0x4C2B4F0: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
  
  ==3799==    by 0x401211: cpy_to_q (handle_q.c:21)
  
  ==3799==    by 0x40177A: rcv_enter code herertp (net_interface.c:142)
  
  ==3799==    by 0x401D89: main (voip_bridge.c:48)
  </code></pre>
  
  <p>Here is what the log says before the issue:</p>
  
  <pre><code>num audio bytes: 6 n
  num_in_q: 14
  REALLOC
  size of q: 94
  bytes: 0bd2d4b5da0f
  num audio bytes: 6
  num_in_q: 20
  REALLOC
  size of q: 100
  bytes: b15c0f0b86f3b15a0f0bd2d4b5da0f0000000000
  bytes: 08cb24ad9a0f
  num audio bytes: 6
  num_in_q: 6
  REALLOC
  size of q: 106 
  bytes: 22c6a0d000e3980ba0f27ccca4336ef243e3168e57150fd6e388b8c7bf
  num audio bytes: 29
  num_in_q: 35
  REALLOC
  size of q: 135
  *** glibc detected *** ./voipBridge: double free or corruption (out): 0x00000000023432f0 ***
  </code></pre>
  
  <p>Also, I realize the queue will just keep getting larger and larger.  Is there a way to free up memory without freeing the entire block?</p>
  
  <p>Thanks.</p>