Reputation: 14892
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
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?
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
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
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
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
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
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
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
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