Rio
Rio

Reputation: 14892

Copying and freeing malloc'ed pointer

I'm trying to hunt down memory leaks and have found one source. I am malloc'in the pointer in one function and freeing it in another, but I'm missing out on understanding how to copy the value the pointer points to while also being able to free the pointer.

Current implementation (with memory leak):

// This code has been greatly simplified
// and as such does not appear to have any purpose
int foo(){
  int bestval = 0;
  char *best;
  char *match;
  for (int i=0;i<3;i++) {
      int returnValue = bar(&best);
      if (returnValue > 10) {
        (1)
         match = best;
      }
  }

  printf("%s", match); 
  (2)    
  return 0;
}


int bar(char ** best) {
  char*s = "Hello!";
  *best = malloc(strlen(s) + 1);
  strcpy(*best,s);
  return 0;
}

Two questions

  1. If I had to free memory at (1) rather than (2), how would I do it so that match would still have what was contained in best?

  2. Should I be doing strcpy to copy best to match? If so, do I have to do another malloc within foo?

Upvotes: 1

Views: 2814

Answers (7)

forsvarir
forsvarir

Reputation: 10839

A bit of a stab in the dark, assuming there's a loop in Foo...

int foo()
{   
    int bestval = 0;   
    char *best;   
    char *match = 0;    // initialize to null

    // start some loop
    for (int i=0;i<3;i++) {       

        // fetch the next best value...
        int returnValue = bar(&best);       
        // some check (if best is really best!)
        if (returnValue > 10) {
            // if match has previously been populated, free it
            if(match) {
                free(match);
            }
            // save the new best value
            match = best;   
        }
        else {
           // not saving best in match, so free it!
           free(best);
        }
    }
    // end some loop

    // only do this if match was successful?!?
    if(match) {
        printf("%s", match);    
        // clean up once the best of the best has been used...
        free(match);
    }
    return 0; 
} 

Upvotes: 1

Gunther Piez
Gunther Piez

Reputation: 30449

In function bar the strcpy should read as

strcpy(*best,s);

In the main function you can copy the value best points to by

strcpy(match, best);
free(best);

match needs to point to a valid memory block before. If you do a

match = best;
free(best);

match will be invalid too because it points at the same freed memory best pointed.

Upvotes: 1

Ben Stott
Ben Stott

Reputation: 2218

Your current assignment simply assigns the pointers to the same buffer. If you then free() this buffer, you've removed what is contained here (and thus dereferencing it is a bad idea).
You don't need to use strcpy() to copy best to match - you'll be better off freeing it after the printf() (or the last point that it is needed). There's no point over-complicating things with an extra function call or six, just remember to free() memory that you've allocated at the end of each function!

Upvotes: 0

Tony Delroy
Tony Delroy

Reputation: 106196

Yes, you can malloc and strcpy:

match = malloc(strlen(best) + 1);
strcpy(match, best);

But, if your implementation provides it you can use the strdup() function which is much easier:

match = strdup(best);

If you don't already have strdup(), it's a good idea to create one yourself.

Upvotes: 0

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272637

Copying the value of a pointer does not copy the underlying memory. So either, don't free(best) until you are done with match, or you will need to malloc a new buffer, and e.g. memcpy() the contents from one buffer to the other.

Upvotes: 0

Mahesh
Mahesh

Reputation: 34625

If I had to free memory at (1) rather than (2), how would I do it so that match would still have what was contained in best?

If you free at position (1), it is not possible to do it so that match would still have what was contained in best.

Should I be doing strcpy to copy best to match? If so, do I have to do another malloc within foo?

  match = best;

With the above statement, both are pointing to the same location. So, there is no need to strcpy at all. To do that, allocate memory for match to point to whose length is best+1 and then do a strcpy.

Upvotes: 0

Arkaitz Jimenez
Arkaitz Jimenez

Reputation: 23198

You need to know the size of the string.
At (1) You would be assigning the address of a memory address that has already been freed, you have to do another malloc to match*=malloc(sizestr) and then copy it with memmove or strcpy if you want to free best.

If I understood properly, you want to copy the string into best, then free bests memory and assign ptr to match? if you free best memory before memmoving or strcpying to another location you lose its contents, and if you want to copy it to another location first you need to allocate the memory where you want to copy it to, so you need 2 mallocs on that code.

Upvotes: 0

Related Questions