why does this code leak? - Unix

This is a discussion on why does this code leak? - Unix ; Hi all, I have a basic question on this code: int main() { char *str; int *num; str = (char *)malloc(20); str ="Hello"; printf("string is %s\n",str); free(str); num = (int *)malloc(20); *num =100; printf("number is %d\n",num); free(num); } Purify Heap ...

+ Reply to Thread
Results 1 to 9 of 9

Thread: why does this code leak?

  1. why does this code leak?

    Hi all,
    I have a basic question on this code:

    int main()
    {
    char *str;
    int *num;

    str = (char *)malloc(20);
    str ="Hello";
    printf("string is %s\n",str);
    free(str);

    num = (int *)malloc(20);
    *num =100;
    printf("number is %d\n",num);
    free(num);
    }

    Purify Heap Analysis (combining suppressed and unsuppressed blocks)
    Blocks Bytes
    Leaked 1 20
    Potentially Leaked 0 0
    In-Use 0 0
    ----------------------------------------
    Total Allocated 1 20

    The free() works for the dynamically allocated int but not for the
    string. Why is that?

    Thanks,
    -B

  2. Re: why does this code leak?

    boyphp wrote:
    > I have a basic question on this code:


    > int main()
    > {
    > char *str;
    > int *num;


    > str = (char *)malloc(20);


    If you're writing C don't cast the return value of malloc(),
    it's useless and will keep the compiler from telling you
    if you forgot to include where malloc() is
    declared.

    > str ="Hello";


    And here's the problem. You throw away the pointer you got
    from malloc() and replace it by a pointer to the string
    literal "Hello". I guess you meant to do

    strcpy( str, "Hello" );

    here, did't you?

    > printf("string is %s\n",str);
    > free(str);


    Now you try to free() memory you never allocated.

    > num = (int *)malloc(20);
    > *num =100;
    > printf("number is %d\n",num);


    I guess you meant here

    printf("number is %d\n",*num);

    > free(num);
    > }


    > The free() works for the dynamically allocated int but not for the
    > string. Why is that?


    It will work for both if you don't throw away the pointer
    you received from malloc().
    Regards, Jens
    --
    \ Jens Thoms Toerring ___ jt@toerring.de
    \__________________________ http://toerring.de

  3. Re: why does this code leak?

    boyphp wrote:
    > Hi all,
    > I have a basic question on this code:


    Add

    #include
    #include

    here, or Strange Things can happen.

    > int main()
    > {
    > char *str;
    > int *num;
    >
    > str = (char *)malloc(20);
    > str ="Hello";


    Right here, you have lost your only pointer to the
    memory reserved by malloc(). You probably meant to write
    `strcpy(str, "Hello");' instead.

    > printf("string is %s\n",str);
    > free(str);


    At this point your program goes completely off the
    rails by trying to execute `free("Hello");' When you
    free() something that was not obtained from malloc() et
    al., there's no telling what kind of trouble will ensue.
    If you are *very* *lucky* the program will crash.

    > num = (int *)malloc(20);
    > *num =100;
    > printf("number is %d\n",num);


    ITYM `*num' instead of `num' here.

    > free(num);
    > }
    >
    > Purify Heap Analysis (combining suppressed and unsuppressed blocks)
    > Blocks Bytes
    > Leaked 1 20
    > Potentially Leaked 0 0
    > In-Use 0 0
    > ----------------------------------------
    > Total Allocated 1 20
    >
    > The free() works for the dynamically allocated int but not for the
    > string. Why is that?


    I'm not intimate with Purify and don't see how you can
    tell which block was freed and which was not (they're both
    20 bytes, and look the same to me), but in any event you
    *have* correctly identified the non-freed block. The reason
    it was not freed is that you didn't call free() on it.

    (It seems odd that a fancy tool like Purify didn't catch
    the `free("Hello")' error -- maybe you need to feed it a few
    more option flags or something.)

    --
    Eric.Sosman@sun.com

  4. Re: why does this code leak?

    because what you are passing to free() is not the pointer you got from
    malloc() before.


    boyphp wrote:

    > str = (char *)malloc(20);
    > str ="Hello";
    > printf("string is %s\n",str);
    > free(str);


    > The free() works for the dynamically allocated int but not for the
    > string. Why is that?
    >
    > Thanks,
    > -B


  5. Re: why does this code leak?

    On Jun 4, 12:24*pm, Joachim Gann wrote:
    > because what you are passing to free() is not the pointer you got from
    > malloc() before.
    >
    >
    >
    > boyphp wrote:
    > > str = (char *)malloc(20);
    > > str ="Hello";
    > > printf("string is %s\n",str);
    > > free(str);
    > > The free() works for the dynamically allocated int but not for the
    > > string. Why is that?

    >
    > > Thanks,
    > > -B- Hide quoted text -

    >
    > - Show quoted text -


    Very educative. You guys are awesome. Thanks :-)

  6. Re: why does this code leak?

    boyphp writes:
    > I have a basic question on this code:


    Which could have been posted to comp.lang.c (and perhaps answered by
    consulting the clc FAQ, ).

    > int main()
    > {
    > char *str;
    > int *num;
    >
    > str = (char *)malloc(20);
    > str ="Hello";
    > printf("string is %s\n",str);
    > free(str);
    >
    > num = (int *)malloc(20);
    > *num =100;
    > printf("number is %d\n",num);
    > free(num);
    > }


    I'll assume you're writing C, not C++. If you're writing C++, some of
    these answers will be a bit different (but then in C++ you should
    probably be using new and delete, or perhaps a vector).

    Add these lines to the top:

    #include
    #include

    Change "int main()" to "int main(void)". The former is ok, but the
    latter is more explicit.

    Indent your code. It doesn't matter much for something this small,
    but it's a good habit.

    Dan't cast the result of malloc. You might have gotten a warning on
    "str = malloc(20);", but that would have been because of the mssiing
    "#include "; the cast doesn't fix the error, it just masks
    it.

    Always check whether malloc() returned a null pointer. Often the best
    thing you can do if it does is to abort the program.

    The assignment ``str = "Hello"'' doesn't copy the value "Hello" to the
    memory to which str points. It modifies the pointer str so it points
    at the string literal. To copy the string, call strcpy() (which
    requires ``#include ''). See section 6 of the comp.lang.c
    FAQ for information about arrays and pointers; it's massively
    confusing if you don't know the rules, but mostly straightforward if
    you do.

    This is where the leak occurs. You assigned the result of malloc to
    str, then you immediately clobbered that value by assigning the
    address of the string literal to str. Later, you pass the address of
    the string literal "Hello" to free(). This invokes undefined
    behavior; it didn't happen to have any visible symptoms in your case,
    but it's potentially Very Bad.

    The code dealing with ``num'' is better. Again, don't cast the
    result of malloc, and check whether it returned a null pointer. You
    allocate 20 bytes, which seems arbitrary, though it's almost certainly
    enough to hold a single int. For this program, the following would be
    better:
    num = malloc(sizeof *num);
    which is equivalent to:
    num = malloc(sizeof(int));
    ("*num" is ok here, since sizeof doesn't evaluate its operand. Using
    "*num" avoids future errors if the type of num changes. sizeof
    applied to an expression doesn't need parentheses.)

    Change
    printf("number is %d\n",num);
    to
    printf("number is %d\n",*num);

    Add "return 0;" before the closing brace. There are circumstances in
    which this isn't necessary, but it never hurts.

    --
    Keith Thompson (The_Other_Keith) kst-u@mib.org
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

  7. Re: why does this code leak?

    On Jun 4, 2:52 pm, boyphp wrote:
    > Hi all,
    > I have a basic question on this code:
    >
    > int main()
    > {
    > char *str;
    > int *num;
    >
    > str = (char *)malloc(20);
    > str ="Hello";
    > printf("string is %s\n",str);
    > free(str);
    >
    > num = (int *)malloc(20);
    > *num =100;
    > printf("number is %d\n",num);
    > free(num);
    >
    > }
    >
    > Purify Heap Analysis (combining suppressed and unsuppressed blocks)
    > Blocks Bytes
    > Leaked 1 20
    > Potentially Leaked 0 0
    > In-Use 0 0
    > ----------------------------------------
    > Total Allocated 1 20
    >
    > The free() works for the dynamically allocated int but not for the
    > string. Why is that?
    >
    > Thanks,
    > -B


    you may want to have a look at valgrind, see:http://valgrind.org/.
    I found more usefull than purify (at least on x86 arch).
    Running it on your program:

    ppi@leo:~$ valgrind --tool=memcheck --leak-check=full ./a.out
    ==7737== Memcheck, a memory error detector.
    ==7737== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et
    al.
    ==7737== Using LibVEX rev 1732, a library for dynamic binary
    translation.
    ==7737== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
    ==7737== Using valgrind-3.2.3-Debian, a dynamic binary instrumentation
    framework.
    ==7737== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et
    al.
    ==7737== For more details, rerun with: -v
    ==7737==
    string is Hello
    ==7737== Invalid free() / delete / delete[]
    ==7737== at 0x402237F: free (vg_replace_malloc.c:233)
    ==7737== by 0x8048418: main (loop.c:9)
    ==7737== Address 0x804851C is not stack'd, malloc'd or (recently)
    free'd
    number is 68681840
    ==7737==
    ==7737== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 11 from
    1)
    ==7737== malloc/free: in use at exit: 20 bytes in 1 blocks.
    ==7737== malloc/free: 2 allocs, 2 frees, 40 bytes allocated.
    ==7737== For counts of detected errors, rerun with: -v
    ==7737== searching for pointers to 1 not-freed blocks.
    ==7737== checked 59,132 bytes.
    ==7737==
    ==7737==
    ==7737== 20 bytes in 1 blocks are definitely lost in loss record 1 of
    1
    ==7737== at 0x4022765: malloc (vg_replace_malloc.c:149)
    ==7737== by 0x80483F0: main (loop.c:6)
    ==7737==
    ==7737== LEAK SUMMARY:
    ==7737== definitely lost: 20 bytes in 1 blocks.
    ==7737== possibly lost: 0 bytes in 0 blocks.
    ==7737== still reachable: 0 bytes in 0 blocks.
    ==7737== suppressed: 0 bytes in 0 blocks.

    Caught 1 invalid free at line 9, and one memory leak at line 6.

    cheers,
    -- paulo

  8. Re: why does this code leak?

    boyphp writes:

    > Hi all,
    > I have a basic question on this code:
    >
    > int main()
    > {
    > char *str;
    > int *num;
    >
    > str = (char *)malloc(20);
    > str ="Hello";
    > printf("string is %s\n",str);
    > free(str);
    >
    > num = (int *)malloc(20);
    > *num =100;
    > printf("number is %d\n",num);
    > free(num);
    > }
    >
    > Purify Heap Analysis (combining suppressed and unsuppressed blocks)
    > Blocks Bytes
    > Leaked 1 20
    > Potentially Leaked 0 0
    > In-Use 0 0
    > ----------------------------------------
    > Total Allocated 1 20
    >
    > The free() works for the dynamically allocated int but not for the
    > string. Why is that?
    >
    > Thanks,
    > -B


    You are reassigning "str" to another area of memory and then illegally
    trying to free "str". You probably want to strcpy "Hello" into the area
    pointed to be str.

  9. Re: why does this code leak?

    ppi wrote:
    > [...]
    > you may want to have a look at valgrind, see: http://valgrind.org/.
    > I found more usefull than purify (at least on x86 arch).


    I also strongly recommend valgrind. It's one of those tools that make
    you *really* happy to do developing in Linux. It very thorough and easy
    to use. I'd say it's the standard leak test tool under Linux.

+ Reply to Thread