Hi there C /C++ experts...

I have a confusion regarding the function free(void *) in C and delete in C++. Suppose there is a pointer named p. In C++, we dynamically allocate memory for p to point at like this

p = new int [10].

,then when we use

delete p

, in typical situations only the memory space for p[0] gets deallocated. And when we use

delete[] p

p then all the memory space from p[0] to p[9] gets deallocated. I know that in C we use calloc() and malloc() to allocate memory dynamically and use free() to dellocate. Now, is this free() equivalent to delete or delete[]? That is does it deallocate memory space for only p[0] or all the memory space from p[0] to p[9]?????

In the case you describe, delete p and delete [] p are the same as far as free() goes, but some runtimes would complain if you dont put in [].

The [] means that the compiler should call the 'vector delete' destructor, which calls the destructor on each element of the array. delete with no brackets just calls the destructor. In other words...

"delete p"

means:

p->~int(); // call the destructor of the object, in this case an int, so it may be skipped by the compiler, but you get the idea...
free(p); // free the space

"delete [] p"

means

for (int i = 0; i < (allocatedsizeof(p) / sizeof(p)); i++)
p.~int(); // destruct the ith object
free(p);

(allocatedsizeof() I made up to mean "the allocated memory size of the pointer()")

So the space allocated by either is always the same, its the destructor calling that is the difference. Some compilers/runtimes track whether an allocate was for a single object or an array, so you need to match your new [] with delete [], even for things like ints that don't have destructors.

Do you think it actually matters?!

If you have:

int a=new int[8]; 
a[0]=23; 
delete a; 
cout<<a[0];

It prints 23. The same thing applies for delete[]. Why bother deallocating it?

I have a question of my own!
If you use:

int *a,n,i=0;
printf("%i",&n)
for (i;i<n;i++)
     a[i]=i;
for (i=0;i<n;i++)
     printf("%i ",a[i]);

It works very well. I DON'T get it!!! a is but a pointer and it doesn't point to anything. Even so it works. For strings, if this declaration is used: char *s,*s2; you may ask if (*s==*s2) .... You can also read it with gets and write it with puts. WHY?? :?: :?: :?:

It's probably bcos u r using a compilers like TURBO C/C++ IDE in DOS mode. The thing is if a pointer(automatic) is not initialized to point to something then it generally contains "garbage values". When u try to store some values to the place pointed by the pointer it actually tries to store the values in that "garbage" address. Now, run time errors will occur if u r using windows based compilers like visual c++. Bcos the place the pointer points to can be very much out of the memory space or resolution delivered to the program. Hence, an memory fault should happen.

And yes a[0] prints 23. Bcos deallocating doesnt delete everything that is contained in that "to be deallocated" memory space. What it actually does is that it makes this memory space available to other applications. If u do not free dynamically allocated memory then the space will always be kept for the program itself and this will not allow other applications to use the memory. Everytime u run a program having a dynamic allocation of memory and do not free the memory then each time u execute the program u lose certain amount of sytem memory gradually, which is referred to as memory leaking.
And even if u have "deallocated" that memory to be pointed by pointer a, the address a points to is still the same. Therefore,a[0] yields the same value, but that is bcos no other application has overwritten anything so far in the address of a[0], which can be used by applications other than ur program at anytime after it has been deallocated. Again, trying to access a[0] after the memory space for a[0] has been deallocated should result in a runtime error in any windows based compiler.

By the way, these are JUST my PURE speculation. Dont bliv anything i said unless verified by other "c/c++ techies" here. I dont even have any visual c++ or devc++. I am still doin my work in Turbo c++ IDE.

To chainsaw,
I havent fully understood what u said, bcos I am halfway through C and now I have to make transition to C++ bcos my course wants me to do so. I dont have crystal clear concept like how delete or delete[] works. So could u bear the pain of explaining what free does in terms of my C knowledge? that would be much appreciated.

TO Asif_NSU:I must admit that in Dev C++ this doesn't work at all. BUT in the DOS version it WORKS very well. I'm using Borlamd C++ 3.1. This thing is highly useful for ME. I will be in the 8th form next year and the compilers used at the Programming Olymphiad are for DOS. Therefor this will work. To ALL C/C++ (FOR DOS) programmers WHY am I allowed to do this???????(see 3rd post) :eek:

>WHY am I allowed to do this???????

You are not allowed to do this. Undefined behavior is, well, undefined behavior. It could behave how you think is "correct", it could crash, it could something completely different.

Now I'll admit, if all undefined behavior required something hideously harsh like reformatting your hard drive, programmers would learn very quickly what not to do. But this kindness granted to us by language implementors should not be overlooked.

To Asif_NSU:

You asked again what free() does. Here's some code....

char* p1 = new char[100];
char* p2 = malloc(100);

// p1 and p2 both point to 100 charactors of allocated memory.  Those calls were functionally idenctical in that sense.

delete [] p1;
free(p2);

// Both of those calls deleted the 100 chars of ram allocated; again they are functionally identical.

Here's where they're different:

class AThingy
{
public:
    AThingy() { printf("Constructor\n"); }
    ~AThingy() { printf("Destructor\n"); }
};

AThingy *t1 = new AThingy[100];
AThingy *t2 = (AThingy*)malloc( sizeof(AThingy) * 100 );

// now t1 and t2 both point to 100 thingys.  However, the new [] call called the constructor of each of the 100 thingys, but malloc did not!

delete [] t1;
free(t2);

// the delete [] called the destructor for all 100 items, the free did not!

// so malloc-->new, free-->delete.

Thanx again chainsaw. Now I get the idea. well, i asked one of my instructors about this, but he did not expalin it in that way. I wish u were my instructor. THANX, big time. :D

TechTalkForums MessageYou must spread some Reputation around before giving it to Chainsaw again.

I did try to bump up ur reputation:D . But that's the message i got:sad: . So, wait till I find someone else worthy of some thumbs up.:cheesy:

To Dave: Thanks a lot. I've figured out why it sometimes would work and other times it would crash! When a pointer is declared in main(), it has a residual adress to a memory block. Therefore, it can be used BUT if more such pointers exist(uninitialized) the result might be that one overwrites the other etc. etc. or it may actually get the text or variables entered in the console before (C gets all information from a place in the PC's memory where all keys are stored->there is a pointer to that mem. block) So, NEVER EVER use a pointer to a mem. block BEFORE allocating it :mad:

free() works similar to both delete and delete[] according to the sittuation it is used.

for example consider:

int *p=(int*)malloc(sizeof(int));
free(p); //de-allocates memory of one integer size {i.e, sizeof(int);}
             // works similar to delete p


int *p=(int*)malloc(sizeof(int*15)); //here 15 is an arbirtrary size
free(p); //de-allocates memory of 15 integers size {i.e, sizeof(int*15);}
             //works similar to delete [] p;

Edited 3 Years Ago by Reverend Jim: Fixed formatting

Comments
Telling us nothing new which wasn't said 5 YEARS AGO!!!!

I hope this does more to help than to confuse, but here goes another answer. The original question was; which is the same as free(), delete or delete[]? It turns out that none of the three are equal. free() simply "returns" the block of memory back to the pool of available memory while delete "knows" if a destructor needs to be called first. delete[] will call the destructor for each object in an array if needed, before "returning" the memory to the pool of available memory. It is also important to match calls of malloc() with free(), new with delete and new[] with delete[].

Just to point some thing s out, posting #3 is filled with unpredictable behavior. The fact that it's unpredictable is why the different compilers don't react to it the same.

1. a could start out pointing to any memory address (in the stack, in the heap, anywhere).

2. The code will then print out the address of n, not the value. (forgot the semicolon )

3. n could be any integer value, there's no telling how many times this thing is going to loop for.

4. now "a = i" is just writing to some location in memory. Hopefully it doesn't write over anything important like a return address.

5. It's a long shot, but possible that "a = i" wrote over the value of n. This may loop a different number of times from before.

6. Most of the time, this will print out the numbers 0 1 2 3... for however many n now holds the value of.

This code also "works" for strings because strings are just arrays of 1 or 2 byte integers (char or wchar_t respectively) in c/c++. It has little chance of actually working with the desired string length in any way though.

Hopefully this sheds some light on what this code is doing.

Thanks for the lovely post Asif_NSU and Chainsaw!

Edited 5 Years Ago by ahtaniv: n/a

This article has been dead for over six months. Start a new discussion instead.