difference between free and delete

M

Mug

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
 
K

Keith Thompson

Mug said:
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/>.
 
P

Peter Nilsson

Mug said:
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.
 
B

Ben Bacarisse

Peter Nilsson said:
Mug said:
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>
 
P

Peter Nilsson

Ben Bacarisse said:
Peter Nilsson said:
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.
 
A

Antoninus Twink

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*.
 
B

Ben Bacarisse

Peter Nilsson said:
Ben Bacarisse said:
Peter Nilsson said:
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>
 
K

Kaz Kylheku

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.
 
B

bartc

Antoninus Twink said:
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()."
 
M

Michael Tsang

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
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-----
 
B

Ben Bacarisse

Michael Tsang said:
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.
 
D

David Thompson

<OT, but I couldn't resist, sorry>
On Tue, 8 Dec 2009 23:00:20 +0000 (UTC), Kaz Kylheku
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>
 
W

Wolfgang Draxinger

Mug said:
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
 
T

Tim Rentsch

Ben Bacarisse said:
Peter Nilsson said:
Ben Bacarisse said:
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.
 

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

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top