Using new for an already valid pointer - c++

If I've already used new to allocate memory to int* p, but then if I want use new again, will the previously allocated memory remain valid?
int *p;
p= new int[5]; //is this going to remain valid after the following statement?
p= new int[10];
If yes, then am I required to delete[] it? I tried doing that but the compiler says that the pointer is valid, so I can't delete it. Is there any other way to get rid of the previously allocated memory?

The second use of new[] is, in itself, completely independent of the first. The second use of new[] does not in any way invalidate the first block of memory that you allocated.
When you allocate memory, you are asking the system to allocate memory, and tell you the address of the memory that it, the system, allocated. It is your responsibility to remember that address so that you can refer to it in the future. You need to be able to refer to the memory in order to access it and eventually deallocate it.
This is your code:
int *p;
p= new int[5];
p= new int[10];
The first assignment records the address of the first allocated block. The second assignment overwrites that value with the address of the second block.
So, the problem you have is that you no longer have a variable that contains the address of the first block of memory. Whilst that first block is still valid, you are unable to refer to it. In particular, since you can no longer refer to it, you cannot deallocate it and so it will be leaked.
If you wish to be able to deallocate both blocks of memory, then you have to be able to refer to both blocks. Which means that you must have two variables to hold the two distinct addresses.
int* p1 = new int[5];
int* p2 = new int[10];
Now you can refer to blocks blocks separately. When you are done, deallocate the memory:
delete[] p1;
delete[] p2;
On the other hand, if you want to delete the memory before allocating a new block, you can do that:
int* p = new int[5];
// use p
detete[] p;
int* p = new int[10];
// use p
delete[] p;

The prev remain somewhere on the heap. You can use valgrind to verify that. If you want to use the sane pointer again and again you might consider to create a function that delete the last allocation and allicate new space each time...

To add to what David Heffernan said, when you have this statement:
int *p;
p= new int[5];
don't think of p as being assigned to the memory that was allocated. The memory exists independently of p, but you're using p as a sort of post-it note to jot down where that memory is located. When you assign a new value to p, you're simply overwriting your note. You haven't done anything to the memory that was allocated-- you just don't know where it is anymore.

If the memory you previously allocated is not needed anymore, you have to use delete [] to free the memory. Otherwise, the memory is still out there, but you have no way to access it any more, thus a memory leak.

You will need to delete[] p; in order to avoid memory leak. The memory doesn't get released by itself. What's the exact information the compiler is giving in terms of "can't delete it"?

Related

Deleting Pointers

I wanted to ask, is dynamically creating a pointer, and then changing a pointer address to something else still deleting the original allocated space?
for example:
int main()
{
int c = 50;
// Memory leak
int * q = new int;
q = & c;
delete q;
}
What exactly is getting deleted or happening?
Thanks!
What exactly is getting deleted or happening?
Memory leaking and undefined behaviour.
When you do q = & c; you are losing your only tracking of the memory allocated by new int. Noone keeps track of this for you, there is no garbage collector, it is simply lost and cannot be recovered.
When you then do delete q; (where q is assigned to &c) you are deleting memory that you didn't allocate, and worse you are deleting memory on the stack. Either of these will result in undefined behavior.
This is an excellent preface into why you should avoid using pointers in circumstances where you don't need them. In this case, there is no reason dynamically allocate your int. If you really need a pointer, use a c++11 smart pointer (or boost if you don't have c++11). There are increasingly rare cases where you really do need a raw c type pointer. You should read Effective Modern c++ Chapter 4 for excellent detail on this subject.
is dynamically creating a pointer, and then changing a pointer address to something else still deleting the original allocated space?
No. delete will deallocate the memory to which its operand points. You must delete the same block of memory that you obtained from new.
int c = 50;
int * q = new int;
int * r = q;
q = & c;
delete q; // WRONG! q points to something you didn't get from new
delete r; // OK! p points to the block you got from new
To be even more clear, delete doesn't care about what variable it operates on, it only cares about what that variable points to. In the last line above, r points to the block that was originally pointed to by q and allocated by new, so you can safely delete it. q points to statically allocated memory, not something you got from new, so you can't delete it.
Instead of changing where q points, though, you can copy the value you want into the space that q points to:
int c = 50;
int * q = new int;
*q = c;
delete q; // OK! q still points to the same place
Here you're changing the value stored in the location to which q points, but you're not changing q itself. q still points to the block you got from new, so it's safe to delete it.
You code will (try to) delete c. There's no memory management or anything like that in C/C++. delete will try to delete whatever the given pointer points to, and and whatever is not deleted (either by calling delete for variables created with a call to new, or by leaving the scope for local variables) will remain in memory until the program ends.
Notice that trying to delete a local variable will propably cause a crash, since delete actually checks (in a very basic manner) what it deletes - at least to know how much memory has actually been allocated at that address. And at this check, it will propably notice that c doesn't include this information, or that it isn't even at the right end of the memory space, so it will crash.
It will crash because c is created in the stack memory section. If you're lucky and the program didn't crash you aren still leaking memory because the q reference is lost.
First answer is to your question:-
I wanted to ask, is dynamically creating a pointer
We don't create a pointer dynamically. Pointers are just a variable like other variable in C and C++. Difference is, pointer is a variable which can store the address of a particular memory location. In run time you just dynamically allocate memory and assign the address of first address location of that memory size into it.
Now what will happen if you don't delete/free the memory and assign a new address to it. In that case memory will not be release/freed and that can not be use anymore as that will never be marked as free by OS. When you free/delete memory O/S mark that area as free to use, and your running process can utilize it in future. That is call proper memory management. Improper memory manage leads your program to memory leak.

Do I need to call delete to a pointer assigned to another pointer?

Say I have this:
char* data = new char[3];
char* tmp = data;
data = new char[3];
after that should I call delete for both pointers like so:
delete[] data;
delete[] tmp;
or is it just for data:
delete[] data;
I tried the first way but it gave me a heap error, the second way didn't cause me any problems, but then what happens to the memory tmp is pointing to, would there be a memory leak there?.
It is important to understand that the delete operator releases any memory that was allocated by a previous new. So depending upon, the occurrence of new, the call to delete for the same allocated memory should match.
In your case, there are two invocation to new, new char[3] assigned to data which was further assigned to tmp. At this point, both tmp and data refers (points) to the same memory location on the heap. A second invocation of new , new char[3] further allocates memory equivalent to 3 character storage and assigns it to data. Thus it would make sense, to call delete twice on both the allocated blocks, refereed individually by tmp and data.

Confusion about delete operator in C++

This looks simple question but my friend debated with me that below program invokes UB. But I think he is incorrect.
Consider following program:
#include <iostream>
int main()
{
int* p=new int[3]();
int* q=p;
for(int i=0;i<3;i++)
std::cout<<q[i]<<' ';
delete[] q;
std::cout<<'\n';
}
Is this program's behavior well defined? What happen if I write delete[] p; instead of delete[] q; ? Is it valid?
Yes the program is well defined. First you create a pointer assigned to newly allocated memory.
int* p=new int[3]();
Then you create another pointer pointing to that memory
int* q=p;
You then use that pointer to assign data into that memory. After that you delete memory which is pointer to q which is the same as p which is okay. The program returns and all is well
delete doesn't care about what variable you use. What is important is that the memory that the pointer points to was created with new and that you only call delete once on the memory.
The pointer returned by the new[] operator is not the start of the allocated memory but rather points to the first object (or the object at index 0). Now, based on the compiler you're using, the run-time system stores the number of objects, n, somewhere where it can be retrieved if you only know the memory location pointed by p.
According to this blog, the deletion of a vector performs this operation in reverse:
When you do "delete[] p", you are saying, "p points to a bunch of
objects, but I'm not telling you how many." In this case, the compiler
needs to generate extra code to keep track of how many it needs to
destruct. This extra information is kept in a "secret place" when the
vector is allocated with "new[]".
Since doing int *q = p essentially points to the same array's 0th object, it is equivalent to call delete[] q and delete[] p.
Operator delete can be applied ONLY to memory (i.e. address) that was allocated with operator new. If you allocate once you should free (detele) also once, does not metter which pointer (variable storing address) is used, so your code is valid.
But, remember, after you delete[] q neither q nor p DO NOT have to be used. The best way is assigne NULL to both pointers.
No UB. It will work fine. Not much to add here.

Object constructed at a predetermined position in memory - SEGFAULT

I have this piece of code
int main()
{
int *b = new int(8);
cout<<" &b = "<<b<<endl;
delete b;
void *place = (void*)0x3c0fa8; //in my output i am getting this value in &b
int *i = new(place) int(8);
system("PAUSE");
return 0;
}
My doubt is that i have allocate space for "b", and deleted it, now if i allocate another integer space, it comes out to be the same location as allocated previously, now if i forcefully put integer value to this value(after delete), i am getting SEGFAULT.
What's wrong in this code?
Thanks.
It is not guaranteed that each time b will be allocated at same memory location, in fact it is extremely uncommon and you should not rely on this.
And for this case, place actually points to an invalid address, and accessing it causes Segfault.
Even if place points to same location where b were allocated, after deleting b, the memory is de-allocated and does not belong to your program. Before int *i = new(place) int(8); gets executed, that memory location may have been allocated by any other process. Hence again accessing it will cause Segfault.
Using memory that was allocated from the heap, after it has been freed (with delete) is undefined behaviour. For all we know, that cell of the heap may have been completely freed back to the OS [and thus no longer available as memory in your process] (in fact, Windows pretty much calls into the OS directly for all heap allocations, and it is possible that it frees the entire lump of memory that the heap is in).
However, it's more likely that the second new call works out, and you are simply overwriting some piece of heap memory that belongs to the heap, so when the code tries to exit (and free some stuff allocated before main), it falls over.
If you were to do it
int main()
{
int *b = new int(8);
cout<<" &b = "<<b<<endl;
// delete b;
int *i = new(b) int(8);
}
it has a good chance of working, since you are no longer using heap memory AFTER it has been freed. (Of course, you may want to change the second 8 to a 9 or something to see the difference... ;)
It looks like you are using the placement new wrong. The placement new operator is used for constructing stuff in a pre-defined location. It's meant to be used like this (This question might be useful too):
char *buffer = new char[sizeof(string)];
string *str = new (buffer) string("hello, world");//<-- this is your placement new
As you can see, the memory in which you are constructing, should be acquired by you in advance. In your example, however, you are not doing it, and trying to write into memory that you have not acquired before, which leads to segfault.
Also, as the other answer mentioned, you are by no means guaranteed to be getting the same address for b each time. Moreover, even if you get lucky, and place points to the same address as b, you still are trying to write into the memory that doesn't belong to you, since you do a delete b beforehand.

What does deleting a pointer mean?

Is deleting a pointer same as freeing a pointer (that allocates the memory)?
Deleting a pointer (or deleting what it points to, alternatively) means
delete p;
delete[] p; // for arrays
p was allocated prior to that statement like
p = new type;
It may also refer to using other ways of dynamic memory management, like free
free(p);
which was previously allocated using malloc or calloc
p = malloc(size);
The latter is more often referred to as "freeing", while the former is more often called "deleting". delete is used for classes with a destructor since delete will call the destructor in addition to freeing the memory. free (and malloc, calloc etc) is used for basic types, but in C++ new and delete can be used for them likewise, so there isn't much reason to use malloc in C++, except for compatibility reasons.
You can't "delete" a pointer variable
Sure you can ;-)
int** p = new int*(new int(42));
delete *p;
delete p; // <--- deletes a pointer
But seriously, delete should really be called delete_what_the_following_pointer_points_to.
Yes, delete is used to deallocate memory and call the destructor for the object involved.
It's common pratice to set pointer to NULL after deleting it to avoid having invalid pointers around:
Object *o = new Object();
// use object
delete o; // call o->~Object(), then releases memory
o = NULL;
When new and delete are used with standard C types in C++ source they behave like malloc and free.
You can't "delete" a pointer variable, only set their value to NULL (or 0).
Yes deleting a pointer is the same as deallocating memory or freeing memory, etc.
Yes and it calls the appropriate destructor.
In short, yes.
But you have to be careful: if you allocate with p = new sometype() only then should you use delete p. If you allocate using p = sometype[count] always use delete [] p
And one more thing: you should never pair malloc/delete or new/free.