简体   繁体   中英

valgrind reports invalid read when mallocing

I am trying to implement a function that uses malloc in it. When I run it using valgrind, it reports the following errors like this:

Invalid read of size 1
==11870==    at 0x4C33DC7: strcmp (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==11870==    by 0x10A864: testFormatAsHex (apintTests.c:212)
==11870==    by 0x109351: main (apintTests.c:72)
==11870==  Address 0x55cd4e1 is 0 bytes after a block of size 1 alloc'd
==11870==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==11870==    by 0x10B989: apint_format_as_hex (apint.c:225)
==11870==    by 0x10A84D: testFormatAsHex (apintTests.c:212)
==11870==    by 0x109351: main (apintTests.c:72)

And there are a lot of invalid writes due to malloc. I really don't understand this, what is the reason of malloc creating invalid writes? I didn't allocate temp_rep anywhere other than in this function, and I made sure to free each temp_rep after testing.


//loop over the array, transforming each u64 number to hex;placing it in array
  //and realloc returning array when placing a char in it
  long length=ap->length;
  int i;
  int hex_pos=0;
  //store the largest without appending zeroes
  if (ap->bin_string[length-1]==0UL){
    char* temp_rep=malloc(sizeof(char));
     temp_rep[hex_pos]='0';
     return temp_rep;
  }
  else{
   
    int most_sig_bits=ceil(log2(apint_get_bits(ap,length-1)));
    int temp_length=ceil((float)most_sig_bits/4);
    char* temp_rep=malloc(temp_length*sizeof(char));
    uint64_t lar_val=ap->bin_string[length-1];
    sprintf(temp_rep,"%lx",lar_val);
  
    //for rest of the terms in array, store them padded
    for(i=length-2;i>=0;i--){
      char *hex_rep=malloc(16*sizeof(char));
      uint64_t val=ap->bin_string[i];
      sprintf(hex_rep,"%016lx",val);
      temp_rep=realloc(temp_rep,sizeof(temp_rep)+sizeof(hex_rep));  
      temp_rep=strcat(temp_rep,hex_rep);
      free(hex_rep);
      }
  return temp_rep;
  }
  
}

The invalid write isn't due to malloc . The message says it's due to a strcmp call that's working with a buffer returned from malloc .

It says it reads past the end of a malloc'ed buffer whose size is 1. That looks suspicious for a string. If you look at where you allocated the memory:

  int hex_pos=0;
  //store the largest without appending zeroes
  if (ap->bin_string[length-1]==0UL){
    char* temp_rep=malloc(sizeof(char));
     temp_rep[hex_pos]='0';
     return temp_rep;
  }

You allocate 1 byte and store the character '0' there. But apparently temp_rep is supposed to be string, which means you didn't null terminate it. You need to allocate one additional byte for the null terminator and set is:

     char* temp_rep=malloc(2);
     temp_rep[0]='0';
     temp_rep[1]=0;
     return temp_rep;

You have similar issues in the else block where you don't leave space for the null terminator, and you're using sizeof on temp_rep and hex_rep (which gets you the size of the pointers, not the string they contain) instead of strlen .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM