memory deallocation

memory deallocation

Post by Cornel Arne » Sat, 26 Jul 2003 20:07:41



Hi there,

I've written a function that 'converts' a structure of type timeval to
a c-string:

char *tv2Str(struct timeval tvX)
{
        char caStr[20];
        char *cpResult;

        sprintf(caStr, "%ld.%ld", tvX.tv_sec, tvX.tv_usec);

        cpResult = (char *)malloc(sizeof(char)*strlen(caStr));
        strcpy(cpResult, caStr);

        return cpResult;

Quote:}

I use it like this:

printf("%s", tv2Str((struct timeval){123, 456}) );

Question:
How (if at all) does the compiler (gcc) ensure that the memory
allocated in the above function is deallocated after the printf call ?

Thanks,
Cornel

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

memory deallocation

Post by Ben Hutching » Sun, 27 Jul 2003 21:45:15


 > Hi there,
 >
 > I've written a function that 'converts' a structure of type timeval to
 > a c-string:
 >
 > char *tv2Str(struct timeval tvX)
 > {
 >         char caStr[20];
 >         char *cpResult;
 >
 >         sprintf(caStr, "%ld.%ld", tvX.tv_sec, tvX.tv_usec);
 >
 >         cpResult = (char *)malloc(sizeof(char)*strlen(caStr));
 >         strcpy(cpResult, caStr);
 >         return cpResult;
 > }

This looks very much like a C program, though it is valid in C++ too.
Are you sure you posted to the right group?

 > I use it like this:
 >
 > printf("%s", tv2Str((struct timeval){123, 456}) );

Struct literals are a GNU extension.

 > Question:
 > How (if at all) does the compiler (gcc) ensure that the memory
 > allocated in the above function is deallocated after the printf call ?

Which memory?  caStr is deallocated when the function exits.  The
memory that cpResult points to must not be deallocated until the
program is done with it, but the compiler doesn't know when that is
so you have to free memory explicitly.  If you want to avoid that
burden, you need a garbage collector such as that at
<http://www.hpl.hp.com/personal/Hans_Boehm/gc/>.

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

memory deallocation

Post by Peter van Merker » Sun, 27 Jul 2003 21:45:54



 > Hi there,
 >
 > I've written a function that 'converts' a structure of type timeval to
 > a c-string:
 >
 > char *tv2Str(struct timeval tvX)
 > {
 >         char caStr[20];
 >         char *cpResult;
 >
 >         sprintf(caStr, "%ld.%ld", tvX.tv_sec, tvX.tv_usec);
 >
 >         cpResult = (char *)malloc(sizeof(char)*strlen(caStr));
 >         strcpy(cpResult, caStr);
 >
 >         return cpResult;
 > }
 >
 > I use it like this:
 >
 > printf("%s", tv2Str((struct timeval){123, 456}) );
 >
 > Question:
 > How (if at all) does the compiler (gcc) ensure that the memory
 > allocated in the above function is deallocated after the printf call ?

No, it doesn't. You have just created a memory leak. Any memory
allocated with malloc() must be explicitly deallocated with free(). To
fix the problem you would have to use tv2Str() like this:

    timeval t = {123, 456};
    char* s = tv2Str(t);
    printf("%s", s);
    free(s);

As you can see it is a bit cumbersome to do the C way. But since you
asked this question in C++ group, you might as well go for a more C++
like solution:
...
#include <cstdio>
#include <string>
#include <sstream>

std::string tv2Str(const timeval& tv)
{
    std::stringstream text;
    text << tv.tv_sec << "." << tv.tv_usec;
    return text.str();

Quote:}

int main()
{
    timeval tv = {123, 456};
    printf("%s", tv2Str(tv).c_str());
    return 0;

Quote:}

And to get rid of the C remnants altogether you might do it like this:

...
#include <iostream>

std::ostream& operator<<(std::ostream& out, const timeval& tv)
{
    out << tv.tv_sec << "." << tv.tv_usec;
    return out;

Quote:}

int main()
{
    timeval tv = {123, 456};
    std::cout << "Time: " << tv;
    return 0;

Quote:}

--
Peter van Merkerk
peter.van.merkerk(at)dse.nl

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

memory deallocation

Post by Mikael Brockma » Sun, 27 Jul 2003 21:50:05


 > Hi there,
 >
 > I've written a function that 'converts' a structure of type timeval to
 > a c-string:
 >
 > [...]
 >
 > Question:
 > How (if at all) does the compiler (gcc) ensure that the memory
 > allocated in the above function is deallocated after the printf call ?

Simple: it doesn't.

If your program does not require thread safety (or if you are willing to
control the use of the function via mutexes or some other locking
construct), you can keep a static buffer inside the function and return a
pointer to that.  Or, since this is C++, you could return an std::string.

 > Thanks,
 > Cornel

You're welcome,
Mikael Brockman

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

memory deallocation

Post by Sebastian Kapfe » Sun, 27 Jul 2003 22:06:09


 > Hi there,

Hi _there_ :-)

 > I've written a function that 'converts' a structure of type timeval to a
 > c-string:
 >
[...]
 >         cpResult = (char *)malloc(sizeof(char)*strlen(caStr));
 >         strcpy(cpResult, caStr);

strcpy copies strlen(caStr)+1 chars to the buffer. You allocated one less.
(There are a few other deficiencies in this function, which I won't
address now.)

BTW: sizeof(char) is 1 by definition.

 >         return cpResult;
 > }
 >
 > I use it like this:
 >
 > printf("%s", tv2Str((struct timeval){123, 456}) );

GCC-specific syntax. BTW, what's wrong with puts? I see no need for printf
here.

 > Question:
 > How (if at all) does the compiler (gcc) ensure that the memory allocated
 > in the above function is deallocated after the printf call ?

Not at all. You didn't tell it to deallocate anything, so it won't. The
canonical solution is called std::string, which encapsulates memory
management. This means a) automatic deallocation when the buffer is no
longer needed and b) No possibility of one-off errors like the one you
committed above. Please look up strings in your favorite C++ textbook. :-)

--
Best Regards,   |   Hi! I'm a .signature virus. Copy me into
  Sebastian      |   your ~/.signature to help me spread!

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

memory deallocation

Post by llewell » Sun, 27 Jul 2003 22:08:17


 > Hi there,
 >
 > I've written a function that 'converts' a structure of type timeval to
 > a c-string:
 >
 > char *tv2Str(struct timeval tvX)
 > {
 >         char caStr[20];
 >         char *cpResult;
 >
 >         sprintf(caStr, "%ld.%ld", tvX.tv_sec, tvX.tv_usec);
 >
 >         cpResult = (char *)malloc(sizeof(char)*strlen(caStr));
 >         strcpy(cpResult, caStr);
 >
 >         return cpResult;
 > }
 >
 > I use it like this:
 >
 > printf("%s", tv2Str((struct timeval){123, 456}) );
 >
 > Question:
 > How (if at all) does the compiler (gcc) ensure that the memory
 > allocated in the above function is deallocated after the printf call
 > ?
[snip]

It doesn't.

The compiler makes no attempt to handle resource (memory, in this
     case) deallocation for you - that is your job. You must document
     that tv2Str returns a pointer to malloc'd memory, and the caller
     of tv2Str must free that memory when they are done with the
     string.

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

memory deallocation

Post by steve at mve dot co » Sun, 27 Jul 2003 22:12:11


<snip>
 >         cpResult = (char *)malloc(sizeof(char)*strlen(caStr));
<snip>

 > How (if at all) does the compiler (gcc) ensure that the memory
 > allocated in the above function is deallocated after the printf call ?

Hi :
Simple answer ... it doesn't .  The caller of this
function will be responsible for deleting the memory.

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

memory deallocation

Post by Thomas Richte » Mon, 28 Jul 2003 01:05:23


Hi,

Quote:> char *tv2Str(struct timeval tvX)
> {
>         char caStr[20];
>         char *cpResult;
>         sprintf(caStr, "%ld.%ld", tvX.tv_sec, tvX.tv_usec);
>         cpResult = (char *)malloc(sizeof(char)*strlen(caStr));
>         strcpy(cpResult, caStr);
>         return cpResult;
> }
> I use it like this:
> printf("%s", tv2Str((struct timeval){123, 456}) );
> Question:
> How (if at all) does the compiler (gcc) ensure that the memory
> allocated in the above function is deallocated after the printf call ?

As simple as it is: It doesn't. It is released as soon as the tv2Str
function is left because it is an automatic variable, thus rendering the
pointer invalid and making your use of the function dangerous. It
"might" appear to work sometimes, but don't count on it.

To prevent this trouble, you'd either
i) declare the string buffer as static and hence giving it a global
lifetime, understanding that there will be only one buffer in the
program and later calls will invalidate the buffers passed out earlier,
ii) manage the memory itself by allocating a buffer in tv2Str and
requiring for the caller to release it after it's done,
iii) use the string class

Greetings,
        Thomas

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

memory deallocation

Post by Francis Glassboro » Mon, 28 Jul 2003 01:06:37




Quote:>I've written a function that 'converts' a structure of type timeval to
>a c-string:

>char *tv2Str(struct timeval tvX)
>{
>        char caStr[20];
>        char *cpResult;

>        sprintf(caStr, "%ld.%ld", tvX.tv_sec, tvX.tv_usec);

>        cpResult = (char *)malloc(sizeof(char)*strlen(caStr));
>        strcpy(cpResult, caStr);

>        return cpResult;
>}

>I use it like this:

>printf("%s", tv2Str((struct timeval){123, 456}) );

>Question:
>How (if at all) does the compiler (gcc) ensure that the memory
>allocated in the above function is deallocated after the printf call ?

It doesn't and it isn't. And you have a real problem in C (which your
code looks like) because there is nothing you can do about it. C++
provides you many solutions, most of which centre round avoiding that
explicit allocation of dynamic resources. Here is a minimalist amendment
to your code (far from being a stylistically elegant solution):

string tv2Str(struct timeval tvX)
{
        char caStr[20];
        sprintf(caStr, "%ld.%ld", tvX.tv_sec, tvX.tv_usec);

        return caStr;

Quote:}

cout << tv2Str(timeval(123, 456));

assuming that you provide timeval with a ctor.

If you cannot use a C++ solution, then please post to
comp.lang.c.moderated instead.

--
ACCU Spring Conference 2003 April 2-5
The Conference you should not have missed
ACCU Spring Conference 2004 Late April
Francis Glassborow      ACCU

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

memory deallocation

Post by Shantanu Gar » Mon, 28 Jul 2003 18:59:44



Quote:> Hi there,

> I've written a function that 'converts' a structure of type timeval to
> a c-string:

> char *tv2Str(struct timeval tvX)
> {
>         char caStr[20];
>         char *cpResult;

>         sprintf(caStr, "%ld.%ld", tvX.tv_sec, tvX.tv_usec);

>         cpResult = (char *)malloc(sizeof(char)*strlen(caStr));
>         strcpy(cpResult, caStr);

>         return cpResult;
> }

> I use it like this:

> printf("%s", tv2Str((struct timeval){123, 456}) );

> Question:
> How (if at all) does the compiler (gcc) ensure that the memory
> allocated in the above function is deallocated after the printf call ?

No! your memory will never get released. This is a memory leak. You
should store that pointer somewhere and delete the pointer after the
printf call.

-Shantanu Garg

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

memory deallocation

Post by Andy Sawye » Mon, 28 Jul 2003 19:38:57



  on 26 Jul 2003 09:06:09 -0400,


 >
 >  > printf("%s", tv2Str((struct timeval){123, 456}) );
 >
 > BTW, what's wrong with puts? I see no need for printf
 > here.

puts always adds a '\n' to the end of the output, which printf
doesn't. The right thing here (assuming the GCC extention) is:

   fputs( tv2Str((struct timeval){123, 456}), stdout );

I strongly suspect that the addtional '\n' provided by puts (but not by
fputs) is why so many C programmers use printf as their "default" output
function, even when puts (or similar) would serve them better. I've
always considered this mismatch between puts/fputs to be a major flaw in
the C library.

Regards,
  Andy S
--
"Light thinks it travels faster than anything but it is wrong. No matter
  how fast light travels it finds the darkness has always got there first,
  and is waiting for it."                  -- Terry Pratchett, Reaper Man

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

memory deallocation

Post by Ulrich Eckhard » Mon, 28 Jul 2003 20:32:26



> char *tv2Str(struct timeval tvX)
> {
>         char caStr[20];
>         char *cpResult;

>         sprintf(caStr, "%ld.%ld", tvX.tv_sec, tvX.tv_usec);

>         cpResult = (char *)malloc(sizeof(char)*strlen(caStr));
>         strcpy(cpResult, caStr);

>         return cpResult;
> }

> I use it like this:

> printf("%s", tv2Str((struct timeval){123, 456}) );

> Question:
> How (if at all) does the compiler (gcc) ensure that the memory
> allocated in the above function is deallocated after the printf call ?

It doesn't, you have a memory leak.

Uli

--
Questions ?
see  C++-FAQ Lite: http://parashift.com/c++-faq-lite/  first !

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

memory deallocation

Post by James Dennet » Tue, 29 Jul 2003 02:01:51




>  > Hi there,

>  > I've written a function that 'converts' a structure of type timeval
> to  > a c-string:  >
>  > char *tv2Str(struct timeval tvX)
>  > {
>  >         char caStr[20];
>  >         char *cpResult;

>  >         sprintf(caStr, "%ld.%ld", tvX.tv_sec, tvX.tv_usec);

>  >         cpResult = (char *)malloc(sizeof(char)*strlen(caStr));
>  >         strcpy(cpResult, caStr);
>  >         return cpResult;
>  > }

> This looks very much like a C program, though it is valid in C++ too.
> Are you sure you posted to the right group?

>  > I use it like this:

>  > printf("%s", tv2Str((struct timeval){123, 456}) );

> Struct literals are a GNU extension.

Also present in C99, I bleive, and under consideration
for C++0x, with a proposal before the committee.

-- James.

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

memory deallocation

Post by Siemel Nara » Tue, 29 Jul 2003 02:09:18




Quote:> #include <cstdio>
> #include <string>
> #include <sstream>
>     timeval tv = {123, 456};
>     printf("%s", tv2Str(tv).c_str());

Because you include <cstdio> that should be std::printf.

--
+++++++++++
Siemel Naran

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

memory deallocation

Post by Sebastian Kapfe » Tue, 29 Jul 2003 02:18:09



>  >  > printf("%s", tv2Str((struct timeval){123, 456}) );

>  > BTW, what's wrong with puts? I see no need for printf here.

> puts always adds a '\n' to the end of the output, which printf doesn't.

Yes, I should have used fputs. Sorry.

Quote:> I strongly suspect that the addtional '\n' provided by puts (but not by
> fputs) is why so many C programmers use printf as their "default" output
> function, even when puts (or similar) would serve them better. I've
> always considered this mismatch between puts/fputs to be a major flaw in
> the C library.

puts and friends are ill-designed, that's right.

int putchar(int c);
int puts(const char *s);
int putc(int c, FILE *stream);
int fputs(const char *s, FILE *stream);
int fputc(int c, FILE *stream);

AFAIK these all are ISO C. IMO putc "may be implemented as a macro",
that's all what makes it different from fputc. putc does take a FILE
pointer, but its function name doesn't begin with "f".  puts appends "\n",
fputs does not.

Sometimes, I think evolution should be forbidden :-)

--
Best Regards,   |   Hi! I'm a .signature virus. Copy me into
 Sebastian      |   your ~/.signature to help me spread!

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

1. Memory deallocation

Hi..
Does Windows cleans the allocated memory by a procces when the process
is
terminated, if No why the resources monitor shows that the allocated
memory
decreases just after the process is (program) terminated.

Please reply soon.

2. xmotd 1.14 beta 2

3. Memory deallocation in Objective C

4. Long Island ISP's with DOV??

5. memory allocation/deallocation

6. Data recovery from damaged drive

7. when deallocation done with auto_ptr<> && Any memory leak problems?

8. Allocating / Deallocation memory - speed hit?

9. Memory auto deallocation problem in c++

10. Call deallocation : TSP or TAPI app ?

11. Verifying WMI/COM resource allocation deallocation

12. Heap Deallocation