简体   繁体   中英

Valgrind memory leak during realloc

I am not sure why Valgrind is reporting memory leak on it?

Pseudocode in .c file:

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

 char* str_alloc(char *str) {
   char* dup = (char*) malloc((strlen(str) + 1) * sizeof(char));
   strcpy((char*) dup, (char*) str);
   return dup;
 }

 void function_c(char **name) {
   int len = 10;
   (void) realloc(*name, 100);
 }

 void function_b(char **name) {
   (void) function_c(name);
 }

 void function_a(char **name) {
   (void) function_b(name);
 }

 int main() {
   char* name = str_alloc("");
   function_a(&name);
   // Do something with name
   free(name);
 }

I am ignoring the value of realloc since I am kind of sure that realloc will always be on same pointer. Allocating/Reallocating from my own memory pool which is quite huge.

Of course, I can not write the code for memory pool here.

So, In what cases shall I expect to come as Valgrind leak? Couple of cases which I thought of:

  • If realloc happens to smaller memory. realloc is guaranteed to take care of it.
  • If realloc fails, then it is supposed to be memory leak. I understand this.

Any other cases?

There is memory leak because you are loosing the memory allocated by realloc .

Syntax for realloc goes as below.

void *realloc(void *ptr, size_t size); 

Note: It is not guaranteed that pointer returned by the realloc will be same as old pointer passed to realloc and one should not depend on it.

Even compiler is also warning you about the same.

warning: ignoring return value of 'realloc', declared with attribute warn_unused_result [-Wunused-result]

 (void) realloc(*name, 100); ^ 

Hence you need to modify your function_c function as below.

 void function_c(char **name) 
 {
     char *newPtr = NULL;
     newPtr  =  realloc(*name, 100);
     *name = newPtr;
 }

I am ignoring the value of realloc since I am kind of sure that realloc will always be on same pointer. Allocating/Reallocating from my own memory pool which is quite huge.

In code that uses the standard malloc/realloc/free interface, you simply cannot make this assumption, even if you think you provided the implementation and you know how it will behave under controlled conditions. Future people working on your code (including yourself, years from now after you've forgotten the details of this project) will assume there's nothing special about how your code uses standard interfaces and they can move the code onto an entirely different C implementation without bringing your special malloc library along.

Also, the C library is entitled to refuse to let you replace these functions, which is what's causing your immediate problem: valgrind forcibly substitutes its own implementation of malloc/realloc/free for whatever you had, an implementation that never returns the same pointer from realloc. This is on purpose, to catch bugs like this one.

If you want to implement a memory pool that makes guarantees such as "resizing an allocation does not move the allocation", then you need to give all of the functions new names (eg pool_alloc , pool_resize , pool_free ).

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