简体   繁体   中英

Valgrind Reports Invalid Realloc

I'm trying to backfill my knowledge of C memory management. I've come from a mostly scripting and managed background, and I want to learn more about C and C++. To that end I've been reading a few books, including one which included this example of using realloc to trim a string of whitespace:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* trim(char* phrase)
{
  char* old = phrase;
  char* new = phrase;

  while(*old == ' ') {
    old++;
  }

  while(*old) {
    *(new++) = *(old++);
  }

  *new = 0;

  return (char*)realloc(phrase, strlen(phrase)+1);
}

int main ()
{
  char* buffer = (char*)malloc(strlen("  cat")+1);
  strcpy(buffer, "  cat");

  printf("%s\n", trim(buffer));

  free(buffer);
  buffer=NULL;

  return 0;
}

I dutifully copied the example, and compiled with c99 -Wall -Wpointer-arith -O3 -pedantic -march=native . I don't get any compile errors, and the app runs and does what's promised in the book, but when I run it against valgrind I get an error about invalid realloc .

==21601== Memcheck, a memory error detector
==21601== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==21601== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==21601== Command: ./trim
==21601== 
==21601== Invalid free() / delete / delete[] / realloc()
==21601==    at 0x402B3D8: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==21601==    by 0x804844E: main (in /home/mo/programming/learning_pointers/trim)
==21601==  Address 0x4202028 is 0 bytes inside a block of size 6 free'd
==21601==    at 0x402C324: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==21601==    by 0x80485A9: trim (in /home/mo/programming/learning_pointers/trim)
==21601==    by 0x804842E: main (in /home/mo/programming/learning_pointers/trim)
==21601== 
==21601== 
==21601== HEAP SUMMARY:
==21601==     in use at exit: 4 bytes in 1 blocks
==21601==   total heap usage: 2 allocs, 2 frees, 10 bytes allocated
==21601== 
==21601== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1
==21601==    at 0x402C324: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==21601==    by 0x80485A9: trim (in /home/mo/programming/learning_pointers/trim)
==21601==    by 0x804842E: main (in /home/mo/programming/learning_pointers/trim)
==21601== 
==21601== LEAK SUMMARY:
==21601==    definitely lost: 4 bytes in 1 blocks
==21601==    indirectly lost: 0 bytes in 0 blocks
==21601==      possibly lost: 0 bytes in 0 blocks
==21601==    still reachable: 0 bytes in 0 blocks
==21601==         suppressed: 0 bytes in 0 blocks
==21601== 
==21601== For counts of detected and suppressed errors, rerun with: -v
==21601== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

So please help me understand why it's consider an invalid realloc. Is the example crap? Is there something I'm missing? I know that according to the specs, realloc expects the pointer to have been created previously by malloc, so is it because the realloc is in another function? Or is valgrind confused because they're in separate functions? I'm not a complete idiot (most days), but right now I kind of feel like one for not seeing the issue.

Thanks in advance!

You're trying to free the original pointer, not the realloc d one. You can fix it by:

buffer = trim(buffer)

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