difference between free and delete

Discussion in 'C Programming' started by Mug, Dec 8, 2009.

  1. Mug

    Mug Guest

    hi all;

    i have a little question on the behaviors of free and delete.(C and C+
    +)

    here's a little program: test.cc
    #include <stdlib.h>

    int main(int argc, const char *argv[])
    {
    char *tmp1 = (char*) malloc(10);
    char * tmp2 = new char [10];
    free(tmp2);
    delete(tmp1);
    return 0;
    }

    i always have impression that free is equivalent to delete,at least in
    some case.
    sure the program compiled and execute without any complain.
    but take an insight look with valgrind :

    zsh/2 9182 % valgrind ./a.out
    ==14833== Memcheck, a memory error detector
    ==14833== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et
    al.
    ==14833== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright
    info
    ==14833== Command: ./a.out
    ==14833==
    ==14833== Mismatched free() / delete / delete []
    ==14833== at 0x4023516: free (in /usr/lib/valgrind/
    vgpreload_memcheck-x86-linux.so)
    ==14833== by 0x8048578: main (in /media/data/Master1_td_tps/C++/tp4/
    a.out)
    ==14833== Address 0x42ca068 is 0 bytes inside a block of size 10
    alloc'd
    ==14833== at 0x4023D04: operator new[](unsigned int) (in /usr/lib/
    valgrind/vgpreload_memcheck-x86-linux.so)
    ==14833== by 0x8048568: main (in /media/data/Master1_td_tps/C++/tp4/
    a.out)
    ==14833==
    ==14833== Mismatched free() / delete / delete []
    ==14833== at 0x402322D: operator delete(void*) (in /usr/lib/
    valgrind/vgpreload_memcheck-x86-linux.so)
    ==14833== by 0x8048584: main (in /media/data/Master1_td_tps/C++/tp4/
    a.out)
    ==14833== Address 0x42ca028 is 0 bytes inside a block of size 10
    alloc'd
    ==14833== at 0x40238FC: malloc (in /usr/lib/valgrind/
    vgpreload_memcheck-x86-linux.so)
    ==14833== by 0x8048558: main (in /media/data/Master1_td_tps/C++/tp4/
    a.out)
    ==14833==
    ==14833==
    ==14833== HEAP SUMMARY:
    ==14833== in use at exit: 0 bytes in 0 blocks
    ==14833== total heap usage: 2 allocs, 2 frees, 20 bytes allocated
    ==14833==
    ==14833== All heap blocks were freed -- no leaks are possible
    ==14833==
    ==14833== For counts of detected and suppressed errors, rerun with: -v
    ==14833== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 19 from
    8)

    sure all blocks are freed , but why valgrind complain on it?

    can some one kindly give an explication, i may be should post the
    question on C++ forum, but i suppose
    in C forum u guys may understand better the things inside.
    Mug
    Mug, Dec 8, 2009
    #1
    1. Advertising

  2. Mug

    Seebs Guest

    Seebs, Dec 8, 2009
    #2
    1. Advertising

  3. Mug <> writes:
    > i have a little question on the behaviors of free and delete.(C and C+
    > +)
    >
    > here's a little program: test.cc
    > #include <stdlib.h>
    >
    > int main(int argc, const char *argv[])
    > {
    > char *tmp1 = (char*) malloc(10);
    > char * tmp2 = new char [10];
    > free(tmp2);
    > delete(tmp1);
    > return 0;
    > }


    The major difference is that free() exists in C, and delete does not.

    [...]

    > sure all blocks are freed , but why valgrind complain on it?
    >
    > can some one kindly give an explication, i may be should post the
    > question on C++ forum, but i suppose
    > in C forum u guys may understand better the things inside.


    No, a C++ forum would be a much better place to ask (though some of
    the resident trolls will probably try to convince you otherwise).

    But just to save you (and the folks in comp.lang.c++)
    a little time, see question 16.13 of the C++ FAQ Lite,
    <http://www.parashift.com/c++-faq-lite/>.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Dec 8, 2009
    #3
  4. On Dec 8, 11:22 am, Keith Thompson <> wrote:
    > Mug <> writes:
    > > i have a little question on the behaviors of free and
    > > delete.(C and C++)
    > >
    > > here's a little program: test.cc
    > > #include <stdlib.h>
    > >
    > > int main(int argc, const char *argv[])


    The signature is...

    int main(int argc, char *argv[])

    The types char ** and const char ** are not compatible.

    > > {
    > >    char *tmp1 = (char*) malloc(10);
    > >    char * tmp2 = new char [10];
    > >    free(tmp2);
    > >    delete(tmp1);
    > >    return 0;
    > > }

    >
    > ... just to save you (and the folks in comp.lang.c++)
    > a little time, see question 16.13 of the C++ FAQ Lite,
    > <http://www.parashift.com/c++-faq-lite/>.


    I don't know if you meant 16.3 as more obvious error, but
    16.13 is applicable to tmp2.

    --
    Peter
    Peter Nilsson, Dec 8, 2009
    #4
  5. Peter Nilsson <> writes:

    >> Mug <> writes:
    >> > i have a little question on the behaviors of free and
    >> > delete.(C and C++)
    >> >
    >> > here's a little program: test.cc
    >> > #include <stdlib.h>
    >> >
    >> > int main(int argc, const char *argv[])

    >
    > The signature is...
    >
    > int main(int argc, char *argv[])
    >
    > The types char ** and const char ** are not compatible.


    True, but the standard does not require that the types used to declare
    main be compatible with int and char ** -- it says "or equivalent"
    rather than "or some other compatible type". I can't summon up any
    enthusiasm for arguing this one way or the other, but if your comment
    is to be taken as a warning that readers won't necessarily know if
    this is permitted or not, then I second it wholeheartedly.

    <snip>
    --
    Ben.
    Ben Bacarisse, Dec 8, 2009
    #5
  6. Ben Bacarisse <> wrote:
    > Peter Nilsson <> writes:
    > >> Mug <> writes:
    > >> > i have a little question on the behaviors of free and
    > >> > delete.(C and C++)
    > >> >
    > >> > here's a little program: test.cc
    > >> > #include <stdlib.h>
    > >> >
    > >> > int main(int argc, const char *argv[])

    > >
    > > The signature is...
    > >
    > >   int main(int argc, char *argv[])
    > >
    > > The types char ** and const char ** are not compatible.

    >
    > True, but the standard does not require that the types used
    > to declare main be compatible with int and char **


    AFAICS, only 'or in some other implementation-defined manner'
    gives any leeway for incompatible types.

    [Note that int main() and int main(void) are compatible.]

    > -- it says "or equivalent"
    > rather than "or some other compatible type".


    Which is interesting. But I look at...

    % type crt.c
    int main(int, char *[]);
    int main(int, const char *[]);

    % gcc -ansi -c crt.c
    crt.c:2: error: conflicting types for 'main'
    crt.c:1: error: previous declaration of 'main' was here

    ....and think that if non-compatible types can be 'equivalent',
    then 'equivalent' can mean just about anything. Under C90, I
    could argue that...

    void main(void) { }

    ....is equivalent to...

    int main(void) { }

    ....since the status returned to the host is unspecified in
    both cases.

    --
    Peter
    Peter Nilsson, Dec 8, 2009
    #6
  7. On 8 Dec 2009 at 21:44, Peter Nilsson wrote:
    > Ben Bacarisse <> wrote:
    >> True, but the standard does not require that the types used
    >> to declare main be compatible with int and char **

    >
    > AFAICS, only 'or in some other implementation-defined manner'
    > gives any leeway for incompatible types.


    Ah, the subject that never grows old or stale - the debate on signatures
    for main().

    Outsiders might wonder at the time and energy spent here plumbing the
    depths of this most fascinating of topics. They might even imagine
    there's not much to be said.

    But they don't *know*.

    In clc, we *know*.
    Antoninus Twink, Dec 8, 2009
    #7
  8. Peter Nilsson <> writes:

    > Ben Bacarisse <> wrote:
    >> Peter Nilsson <> writes:
    >> >> Mug <> writes:
    >> >> > i have a little question on the behaviors of free and
    >> >> > delete.(C and C++)
    >> >> >
    >> >> > here's a little program: test.cc
    >> >> > #include <stdlib.h>
    >> >> >
    >> >> > int main(int argc, const char *argv[])
    >> >
    >> > The signature is...
    >> >
    >> >   int main(int argc, char *argv[])
    >> >
    >> > The types char ** and const char ** are not compatible.

    >>
    >> True, but the standard does not require that the types used
    >> to declare main be compatible with int and char **

    >
    > AFAICS, only 'or in some other implementation-defined manner'
    > gives any leeway for incompatible types.
    >
    > [Note that int main() and int main(void) are compatible.]
    >
    >> -- it says "or equivalent"
    >> rather than "or some other compatible type".

    >
    > Which is interesting. But I look at...
    >
    > % type crt.c
    > int main(int, char *[]);
    > int main(int, const char *[]);
    >
    > % gcc -ansi -c crt.c
    > crt.c:2: error: conflicting types for 'main'
    > crt.c:1: error: previous declaration of 'main' was here
    >
    > ...and think that if non-compatible types can be 'equivalent',
    > then 'equivalent' can mean just about anything.


    Yes, that is my worry. On the there side, if equivalent means
    compatible, why not just say so? I am baffled by the introduction of
    a new term.

    <snip>
    --
    Ben.
    Ben Bacarisse, Dec 8, 2009
    #8
  9. Mug

    Kaz Kylheku Guest

    On 2009-12-08, Mug <> wrote:
    > hi all;
    >
    > i have a little question on the behaviors of free and delete.(C and C+
    > +)
    >
    > here's a little program: test.cc
    > #include <stdlib.h>
    >
    > int main(int argc, const char *argv[])
    > {
    > char *tmp1 = (char*) malloc(10);
    > char * tmp2 = new char [10];
    > free(tmp2);
    > delete(tmp1);
    > return 0;
    > }
    >
    > i always have impression that free is equivalent to delete,at least in
    > some case.


    It may be the case in your toolchain adn platform that you can free the
    underlying memory which came from delete using free. But the mismatch is an
    error which causes the C++ program's behavior to become not defined
    by the C++ language.

    Even if delete liberates memory by passing the pointer to the same deallocator
    that is also used by the free function (which need not be the case at all), the
    delete operator does something which free does not: namely it calls the
    destructor of a class object which has one.

    The array delete [] operator is even more different: it knows exactly how large
    the array is that is being freed, and invokes the destructors on all of its
    elements.

    There are implementations of new [] and delete [] which use malloc
    and free for the memory, but they add an extra header to the allocated
    memory which tells them how many elements there are in the array.
    On such an implementation, the pointer returned by new [] is not
    the same value that came from free, even if the memory came
    from free; the pointer returned is adjusted to skip past the header
    which tells delete [] how large the array is. Such a header could still be
    reserved by new [] even if an array of a basic type or of ``plain old data
    structure'' type without a constructor is being allocated.

    Basically, you must never mismatch any of these functions and operators if you
    want your code to be portable, reliable and free of resource leaks (due to
    failing to call destructors).

    > sure the program compiled and execute without any complain.
    > but take an insight look with valgrind :


    Valgrind is right in diagnosing the problem, because it's a serious
    coding error. This is not just some annoying ``false positive''.
    To ``shut up'' this diagnostic, you should fix the mismatches.

    > sure all blocks are freed , but why valgrind complain on it?


    Such a mismatch error is not exactly a memory leak. (It could have the same
    consequences as a memory leak, but that's because it's undefined behavior; any
    consequences are possible).

    Leaks can be caused by code which is well-defined; i.e. does nothing else wrong
    other than losing references to objects. By contrast, this code is undefined.

    Valgrind does the right thing by counting these allocator mismatches as errors
    rather than leaks.

    A tool which double-counts the same error by reporting it in multiple
    categories is a tool which is less than accurate.
    Kaz Kylheku, Dec 8, 2009
    #9
  10. Mug

    bartc Guest

    "Antoninus Twink" <> wrote in message
    news:...
    > On 8 Dec 2009 at 21:44, Peter Nilsson wrote:
    >> Ben Bacarisse <> wrote:
    >>> True, but the standard does not require that the types used
    >>> to declare main be compatible with int and char **

    >>
    >> AFAICS, only 'or in some other implementation-defined manner'
    >> gives any leeway for incompatible types.

    >
    > Ah, the subject that never grows old or stale - the debate on signatures
    > for main().
    >
    > Outsiders might wonder at the time and energy spent here plumbing the
    > depths of this most fascinating of topics. They might even imagine
    > there's not much to be said.


    I found this post from a Mr A. Twink (April 2008) says everything there is
    to say about declaring main():

    "Interesting! I often start with int main(void) but then later find I need
    to process command-line arguments, so I change it to int main(int argc, char
    **argv).

    Sometimes for quick throwaway programs, I naughtily use implicit int and
    just have main()."

    --
    Bartc
    bartc, Dec 9, 2009
    #10
  11. -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1

    bartc wrote:

    > Sometimes for quick throwaway programs, I naughtily use implicit int and
    > just have main()."
    >

    Implicit int has been removed from the language already. A conforming
    compiler won't compile this.
    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.9 (GNU/Linux)

    iEYEARECAAYFAksjsrEACgkQG6NzcAXitM90MQCeOPn/FxQDcJnADSEhaKzSgWqh
    N1cAnRTlHtJUSfXOY/in0Rvc3sVW+9T5
    =Uo6L
    -----END PGP SIGNATURE-----
    Michael Tsang, Dec 12, 2009
    #11
  12. Michael Tsang <> writes:

    > bartc wrote:
    >
    >> Sometimes for quick throwaway programs, I naughtily use implicit int and
    >> just have main()."
    >>

    > Implicit int has been removed from the language already. A conforming
    > compiler won't compile this.


    A conforming compiler is entitled to compile it if it wants to,
    provided it issues a diagnostic.

    --
    Ben.
    Ben Bacarisse, Dec 12, 2009
    #12
  13. <OT, but I couldn't resist, sorry>
    On Tue, 8 Dec 2009 23:00:20 +0000 (UTC), Kaz Kylheku
    <> wrote:
    <snip C++new/delete vs malloc/free>
    > It may be the case in your toolchain adn platform that you can free the
    > underlying memory which came from delete using free. But the mismatch is an
    > error which causes the C++ program's behavior to become not defined
    > by the C++ language.
    >

    Yes. And this is the most important point.

    > Even if delete liberates memory [the same way as free] the
    > delete operator [also] calls the destructor [if any]
    >

    If this were the *only* issue you *could* use the ugly obj->~dtor()
    kludge. And conversely malloc plus an inplace ctor instead of new.

    > The array delete [] operator is even more different: it knows exactly how large
    > the array is that is being freed, and invokes the destructors on all of its
    > elements.
    >

    Similarly but even worse.

    > There are implementations of new [] and delete [] which use malloc
    > and free for the memory, but they add an extra header to the allocated
    > memory which tells them how many elements there are in the array.
    > On such an implementation, the pointer returned by new [] is not
    > the same value that came from free, even if the memory came
    > from free; the pointer returned is adjusted to skip past the header


    ..-1,.s/free/malloc/

    > which tells delete [] how large the array is. Such a header could still be
    > reserved by new [] even if an array of a basic type or of ``plain old data
    > structure'' type without a constructor is being allocated.
    >

    Yes again.

    <snip rest>
    David Thompson, Dec 17, 2009
    #13
  14. Mug wrote:

    > hi all;
    >
    > i have a little question on the behaviors of free and delete.(C and C+
    > +)
    >
    > here's a little program: test.cc
    > #include <stdlib.h>
    >
    > int main(int argc, const char *argv[])
    > {
    > char *tmp1 = (char*) malloc(10);
    > char * tmp2 = new char [10];
    > free(tmp2);
    > delete(tmp1);
    > return 0;
    > }


    > sure all blocks are freed , but why valgrind complain on it?


    Because you're NOT using the delete _operator_ in the right way. Thus at
    most only the very first element of tmp2 might be freed, if any at all.

    You allocated using new[], so you've free using delete[]:

    char * tmp2 = new char[10];
    //...
    delete[] tmp2;

    IMHO this is one of the most f***ed up syntax definitions of C++. It would
    make a lot moer sense, and keep such mistakes like your's away, if there was
    only a single form of delete.

    > can some one kindly give an explication, i may be should post the
    > question on C++ forum, but i suppose


    Yes, better ask there :) I f'up2ed there.

    > in C forum u guys may understand better the things inside.


    No, C and C++ are different languages, which happen to share a lot of syntax
    elements and idioms, which makes them somewhat compatible. In you case you
    just made a (very common) mistake.


    Wolfgang
    Wolfgang Draxinger, Dec 17, 2009
    #14
  15. Mug

    Tim Rentsch Guest

    Ben Bacarisse <> writes:

    > Peter Nilsson <> writes:
    >
    >> Ben Bacarisse <> wrote:
    >>> Peter Nilsson <> writes:
    >>> >> Mug <> writes:
    >>> >> > i have a little question on the behaviors of free and
    >>> >> > delete.(C and C++)
    >>> >> >
    >>> >> > here's a little program: test.cc
    >>> >> > #include <stdlib.h>
    >>> >> >
    >>> >> > int main(int argc, const char *argv[])
    >>> >
    >>> > The signature is...
    >>> >
    >>> > int main(int argc, char *argv[])
    >>> >
    >>> > The types char ** and const char ** are not compatible.
    >>>
    >>> True, but the standard does not require that the types used
    >>> to declare main be compatible with int and char **

    >>
    >> AFAICS, only 'or in some other implementation-defined manner'
    >> gives any leeway for incompatible types.
    >>
    >> [Note that int main() and int main(void) are compatible.]
    >>
    >>> -- it says "or equivalent"
    >>> rather than "or some other compatible type".

    >>
    >> Which is interesting. But I look at...
    >>
    >> % type crt.c
    >> int main(int, char *[]);
    >> int main(int, const char *[]);
    >>
    >> % gcc -ansi -c crt.c
    >> crt.c:2: error: conflicting types for 'main'
    >> crt.c:1: error: previous declaration of 'main' was here
    >>
    >> ...and think that if non-compatible types can be 'equivalent',
    >> then 'equivalent' can mean just about anything.

    >
    > Yes, that is my worry. On the there side, if equivalent means
    > compatible, why not just say so? I am baffled by the introduction of
    > a new term.


    Using 'or equivalent' clearly (IMO anyway) means to include a
    definition such as

    int main( argc, argv )
    int arg;
    char *argv[];
    { ... }

    I believe the Standard means to allow this writing of 'main'. Because
    of that, I think it also means to allow the 'int main(){ ... }' form
    as well. Does anything think the Standards means to disallow the
    K&R style version of main given above? Doing so would make illegal
    tons of legacy code.

    To answer the question asked -- because what's being talked about are
    definitions, not types, it's just easier to write 'or equivalent'.
    Perhaps a poor choice for the writing, but an understandable one.
    Tim Rentsch, Jan 12, 2010
    #15
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. CW
    Replies:
    0
    Views:
    548
  2. jakk
    Replies:
    4
    Views:
    12,028
  3. Sid
    Replies:
    5
    Views:
    1,063
  4. Replies:
    4
    Views:
    457
    James Kanze
    Nov 17, 2008
  5. Wolfgang Draxinger

    Re: difference between free and delete

    Wolfgang Draxinger, Dec 17, 2009, in forum: C++
    Replies:
    2
    Views:
    454
    James Kanze
    Dec 17, 2009
Loading...

Share This Page