When it will be freed?

T

tfelb

Hi group!

There are many string functions out there and many use malloc/calloc
mechanisms /but/ they aren't freed before the function returns? When
it will be freed? Because if I use strdup many times the function
malloc's every time more space from the heap or is my thesis wrong?

I saw many implementations of strdup and they all are similar

char *strdup(char *s1)
{

char *newString;
newString = (char *)malloc(strlen(s1) + 1); /* I know casting
malloc isn't necessary
strcpy(newString,s1);
return newString; /* no freeing */
}

Thank you!

Tom F.
 
B

Ben Bacarisse

tfelb said:
There are many string functions out there and many use malloc/calloc
mechanisms /but/ they aren't freed before the function returns? When
it will be freed? Because if I use strdup many times the function
malloc's every time more space from the heap or is my thesis wrong?

That's right. The program using the function need to free the
space when it know there is not more use for it. Only the programmer
knows when this is.
I saw many implementations of strdup and they all are similar

char *strdup(char *s1)
{

char *newString;
newString = (char *)malloc(strlen(s1) + 1); /* I know casting
malloc isn't necessary
strcpy(newString,s1);
return newString; /* no freeing */
}

const char * would be a better type for the parameter and something
other then undefined behaviour should happen when malloc returns NULL.
 
R

Rafael

tfelb escreveu:
Hi group!

There are many string functions out there and many use malloc/calloc
mechanisms /but/ they aren't freed before the function returns? When
it will be freed? Because if I use strdup many times the function
malloc's every time more space from the heap or is my thesis wrong?

I saw many implementations of strdup and they all are similar

char *strdup(char *s1)
{

char *newString;
newString = (char *)malloc(strlen(s1) + 1); /* I know casting
malloc isn't necessary
strcpy(newString,s1);
return newString; /* no freeing */
}

Memory free'd on caller side, maybe? You are receiving a pointer to
char... you can just do

char *whatever = strdup(whatothereverchar);

if(whatever)
free(whatever);


Rafael
 
R

Richard

tfelb said:
Hi group!

There are many string functions out there and many use malloc/calloc
mechanisms /but/ they aren't freed before the function returns? When
it will be freed? Because if I use strdup many times the function
malloc's every time more space from the heap or is my thesis wrong?

It is your responsible to free them.
I saw many implementations of strdup and they all are similar

char *strdup(char *s1)
{

char *newString;
newString = (char *)malloc(strlen(s1) + 1); /* I know casting
malloc isn't necessary

And is bad. Apparently but I never saw any side affects. The "danger" is
a c.l.c thing but why tempt fate? Remove the cast.
strcpy(newString,s1);
return newString; /* no freeing */
}


Something (untested) like this is fine IMO.

char * strdup(char *s){
return strcpy(malloc(strlen(s)+1),s);
}

Perfect. Nice crash if you run out of malloc space too. But if you do
then the system is hosed anyway.....
 
J

Joachim Schmitz

Rafael said:
tfelb escreveu:

Memory free'd on caller side, maybe? You are receiving a pointer to
char... you can just do

char *whatever = strdup(whatothereverchar);

if(whatever)
free(whatever);

As free(NULL); is perfectly legal (and a NOP), you can even drop the if
(whatever) and save the cycles

Bye, Jojo
 
D

David Resnick

> There are many string functions out there and many use malloc/ calloc
mechanisms /but/ they aren't freed before the function returns? When
it will be freed? Because if I use strdup many times the function
malloc's every time more space from the heap or is my thesis wrong?

I saw many implementations of strdup and they all are similar

char *strdup(char *s1)
{

   char *newString;
   newString = (char *)malloc(strlen(s1) + 1); /* I know casting
malloc isn't necessary
   strcpy(newString,s1);
   return newString;  /* no freeing */

}

strdup is non-standard but widely used. Accessing your system
documentation will probably tell you something like this seen on
linux:

The strdup() function returns a pointer to a new string which
is a duplicate of the string s. Memory for the new string is obtained
with malloc(3), and can be freed with free(3).

i.e. when you are done with the string returned, you should call free
on the returned pointer or you will leak memory.

The above is a subpar implementation of strdup for a number of reasons
not relevant to your question, btw. Some things that might be done
differently:

1) name is in implementation namespace (strx), but whatever, it is a
very common
extension, I expect any future standard function named "strdup"
would have
identical signature and semantics to the widely available one.
So no big
problem presumably.
2) Argument should really be const char*.
3) Doesn't check argument for NULL
4) Doesn't check malloc for success (at least on my system is
documented to set
errno to ENOMEM on malloc failure)
5) Casts malloc (which you noted, discussed to death, so whatever)
6) I'd rather use memcpy (since the strlen is already measured once in
fn)

Some of the above are just design decisions I guess...

-David
 
T

tfelb

 > There are many string functions out there and many use malloc/
calloc










strdup is non-standard but widely used.  Accessing your system
documentation will probably tell you something like this seen on
linux:

       The strdup() function returns a pointer to a new string which
is a duplicate of the string s.  Memory for the new string is obtained
with malloc(3), and can  be  freed with free(3).

i.e. when you are done with the string returned, you should call free
on the returned pointer or you will leak memory.

The above is a subpar implementation of strdup for a number of reasons
not relevant to your question, btw.  Some things that might be done
differently:

1) name is in implementation namespace (strx), but whatever, it is a
very common
      extension, I expect any future standard function named "strdup"
would have
      identical signature and semantics to the widely available one..
So no big
      problem presumably.
2) Argument should really be const char*.
3) Doesn't check argument for NULL
4) Doesn't check malloc for success (at least on my system is
documented to set
         errno to ENOMEM on malloc failure)
5) Casts malloc (which you noted, discussed to death, so whatever)
6) I'd rather use memcpy (since the strlen is already measured once in
fn)

Some of the above are just design decisions I guess...

-David- Zitierten Text ausblenden -

- Zitierten Text anzeigen -

Thank you! This was a test function with no built-in checks.
 
S

Stephen Sprunk

Gordon said:
strdup() (not a standard C function) wouldn't be very useful if it
kept re-using the same memory to store strings.

Exactly. One of the common uses for strdup() is to "fix" functions that
return a pointer to a static buffer, so if strdup() did the same thing,
it'd be rather pointless.

S
 
R

Rafael

Joachim Schmitz escreveu:
As free(NULL); is perfectly legal (and a NOP), you can even drop the if
(whatever) and save the cycles

Wouldn't I save a cycle not calling free?

Rafael
 
R

Richard Tobin

As free(NULL); is perfectly legal (and a NOP), you can even drop the if
(whatever) and save the cycles
[/QUOTE]
Wouldn't I save a cycle not calling free?

Several, but only when strdup() failed, which Is hardly ever going to
be true.

Either way, the difference is unlikely to be noticable.

-- Richard
 
J

jameskuyper

Rafael said:
Joachim Schmitz escreveu:


Wouldn't I save a cycle not calling free?

That depends upon what your code is doing. In typical contexts, I
write

p = malloc(*p);
if(p)
{
// Code which uses p

free(p);
}

In such contexts, I already need the if() just to protect the other
code which uses p; putting the free() inside the if() block rather
than outside of it saves an unnecessary function call, at no extra
cost.

However, in this case you just have

if(whatever)
free(whatever);

That performs one extra comparison every time the if() statement is
executed; it saves you one function call every time that 'whatever' is
a null pointer. Whether or not that gives you a net speed-up depends
upon the how much time the comparison takes, compared to the overhead
of a function call, but it also depends upon how often 'whatever' is
null. For most of the programs I write, a malloc() failure usually
requires premature termination of the program, so if malloc() failures
were common, they would indicate poor program design - the work to be
done needs to be broken down into pieces small enough to avoid putting
so much strain on the available memory. As a result, I would seldom
write such code. However, there might be contexts where non-fatal
malloc() failures are more common than in my code.
 
S

Stephen Sprunk

Rafael said:
Joachim Schmitz escreveu:


Wouldn't I save a cycle not calling free?

Only in the case where the malloc() inside strdup() failed, which should
be rare enough to not worry about. However, you will usually be
checking the return value of strdup() to avoid passing a NULL to other
functions that aren't defined to handle it properly, so the free()
probably won't end up in the execution path anyways.

S
 
R

Rafael

Richard Tobin escreveu:
Wouldn't I save a cycle not calling free?

Several, but only when strdup() failed, which Is hardly ever going to
be true.

Either way, the difference is unlikely to be noticable.[/QUOTE]

Your'e right.... I'll better find out if strdup failed on call. If yes,
just take another course.

char *whatever;

int docomplain()
{
printf("Problems\n");
return EXIT_FAILURE;
}

if( (whatever = strdup(whatothereverchar))==NULL)
return docomplain();

free(whatever);
 
R

Rafael

jameskuyper escreveu:
That depends upon what your code is doing. In typical contexts, I
write

I've figured that... take a look on my reply to Richard Tobin. Its kind
of the same, but not being the same. ...?


Rafael
 
R

Rafael

Stephen Sprunk escreveu:
Only in the case where the malloc() inside strdup() failed, which should
be rare enough to not worry about. However, you will usually be
checking the return value of strdup() to avoid passing a NULL to other
functions that aren't defined to handle it properly, so the free()
probably won't end up in the execution path anyways.

S
I really should read all feedbacks before post anything.


I've figured that... take a look on my reply to Richard Tobin. Its kind
of the same, but not being the same. ...?


Rafael
 
J

jameskuyper

Rafael said:
jameskuyper escreveu:


I've figured that... take a look on my reply to Richard Tobin. Its kind
of the same, but not being the same. ...?

The code you wrote is only fragments that don't work together. It
includes a declaration of a function, which must occur at file scope,
with executable statements which could only occur in block scope. It
also has a declaration of an object that could legally occur at either
file scope or block scope, but would probably constitute poor design
at file scope.
It allocates memory for a copy of a string, and then does nothing with
the copy before free()ing that memory. I presume that these fragments
are meant to exist in a larger context where they all make sense
together, but it would be easier to judge whether or not they're
correct if you would show them in a simplified version of that
context.
 
R

Rafael

jameskuyper escreveu:
The code you wrote is only fragments that don't work together.

Yeah... even to myself, that's confusing.
> correct if you would show them in a simplified version of that
> context.

Not willing to be a complete implementation (since even strdup
declaration is not here, and no includes, but now one can figure, and I
can train my lazyness neural network):

int docomplain()
{
printf("Problems\n");
return EXIT_FAILURE;
}

int main(int argc, char **argv)
{
char *whatever;

if( (whatever = strdup(whatothereverchar))==NULL)
return docomplain();

/*handle whatever*/

free(whatever);

return EXIT_SUCCESS;
}


Rafael
 
J

jameskuyper

Rafael said:
jameskuyper escreveu:

Yeah... even to myself, that's confusing.


Not willing to be a complete implementation (since even strdup
declaration is not here, and no includes, but now one can figure, and I
can train my lazyness neural network):

int docomplain()
{
printf("Problems\n");
return EXIT_FAILURE;
}

int main(int argc, char **argv)
{
char *whatever;

if( (whatever = strdup(whatothereverchar))==NULL)

I'd re-write that as

char *whatever = strdup(whatothereverchar);
if(whatever == NULL)

but that's just a matter of style.
return docomplain();
/*handle whatever*/

free(whatever);

return EXIT_SUCCESS;
}

Structured programming purists would object to the early return from
main(). I'm not such a purist, though I recognize that there's some
validity in their objections to such code.
 
R

Rafael

jameskuyper escreveu:
Structured programming purists would object to the early return from
main(). I'm not such a purist, though I recognize that there's some
validity in their objections to such code.

Sorry, but I don't think I get the "early return" meaning...
What should I do? Write more fake code?

I didn't even told you where whatothereverchar comes from... :)

Rafael
 
S

Stephen Sprunk

Rafael said:
jameskuyper escreveu:

Sorry, but I don't think I get the "early return" meaning...
What should I do? Write more fake code?

Some programmers do not like the idea of multiple return points from a
function; they want all code paths to reach a single return point at the
end of the function. They often extend the same logic to main(),
basically banning the use of exit() and requiring all functions to
return so that (the first instance of) main() returns from a single point.

While there are some advantages to having a single return point, more
pragmatic programmers believe that complex code is often easier to
understand with multiple return (or exit()) points. This is not unlike
the debate about "goto"; avoiding it is a good idea in general, but
there are times it's the best tool for the job.

S
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top