Why do I get an error deleting a dynamic pointer? - c++

Please don't come and say "jUst read the error", it doesn't specify it, that's why Im asking here.
int main()
{
int* p, * q;
int a = 10;
p = new int;
p = &a;
delete p;
}

p = new int
In this line, you dynamically allocate the memory that you need to delete.
p = &a
But in this line, you are not allocating new memory, you are pointing p at stack memory, and leaking the memory that you previously allocated.

Related

What happens to values on the stack that get placed in array on the Heap

I want to know if I create an array on the Heap in C++ and I assign data from the stack to the Array, what exactly happens? Is the data copied onto the heap?
code fragment:
int a = 1;
int b = 2;
int *c = new int(3);
int *arr = new int[3];
arr[0] = a;
arr[1] = b;
arr[2] = *c;
int a = 3;
a has the value 3.
the memory address of a is 0x345A or something like it.
a is on the stack.
int *p = &a;
pointer p is assigned the address of a. The memory address of p is 0x123B or something like it. That memory address holds the value 0x345A pointing to the location where the value 3 is stored. Pointer p is on the stack.
You'd get 3 if you print a and *p since they are getting their value from the same memory location.
You'd get 0x345A if you print &a and p since a's address is the value p holds.
You'd get 0x123B if you print &p since that is the memory location for pointer p.
Assuming *c points to an integer on the heap, you could store the value of c (which is the memory address of the integer on heap) in an array.
int *arr = new int[3];
...
arr[2] = c;
What you do NOT want to do is:
int foo = 10;
arr[2] = &foo;
Now, your array is pointing to a memory location that that is on the stack. Will work OK as long as you are in that function, but will be pointing at garbage once you exit the function and stack is reclaimed.

c++ delete pointer and then access the value of it points to

I just learned pointer and delete pointer in class for C++. I tried this code by my own
# include<iostream>
using namespace std;
int main(){
int num = 10;
int *p = new int;
p = &num;
cout << *p << endl;
delete p;
cout << num << endl;
return 0;
}
After deleting the pointer p, I cannot print the value of num. But if I delete p at the very end of the program, cout << num << endl; will give me 10. Anyone knows where I did run?
You first leaked a pointer
int *p = new int;
p = &num; // You just leaked the above int
then illegally deleted something you did not new
delete p; // p points to num, which you did not new
You have already received a couple of good answers that point out the mistake, but I read a deeper misunderstanding of the allocation and deallocation of heap vs stack variables.
I realised this has become a pretty long post, so maybe if people think it is useful I should put it as a community Wiki somewhere. Hopefully it clarifies some of your confusion though.
Stack
The stack is a limited and fixed size storage. Local variables will be created here if you don't specify otherwise, and they will be automatically cleaned up when they are no longer needed. That means you don't have to explicitly allocate them - they will start existing the moment you declare them. Also you don't have to deallocate them - they will die when they fall out of scope, loosely speaking: when you reach the end brace of the block they are defined in.
int main() {
int a; // variable a is born here
a = 3;
a++;
} // a goes out of scope and is destroyed here
Pointers
A pointer is just a variable, but instead of an int which holds a whole number or a bool which holds a true/false value or a double which holds a floating point, a pointer holds a memory address. You can request the address of a stack variable using the address operator &:
{
int a = 3, b = 4;
int* p = &a; // p's value is the address of b, e.g. 0x89f2ec42
p = &b; // p now holds the address of b, e.g. 0x137f3ed0.
p++; // p now points one address space further, e.g. 0x137f3ed4
cout << p; // Prints 0x137f3ed4
} // Variables a, b and p go out of scope and die
Note that you should not assume that a and b are "next to" each other in memory, or that if p has a "used" address as its value then you can also read and write to the address at p + 1.
As you probably know, you can access the value at the address by using the pointer indirection operator, e.g.
int* p = &a; // Assume similar as above
*p = 8;
cout << a; // prints 8
cout << &a << p; // prints the address of a twice.
Note that even though I am using a pointer to point at another variable, I don't need to clean up anything: p is just another name for a, in a sense, and since both p and what it points to are cleaned up automatically there is nothing for me to do here.
Heap
The heap memory is a different kind of memory, which is in theory unlimited in size. You can create variables here, but you need to tell C++ explicitly that you want to do so. The way to do this is by calling the new operator, e.g. new int will create an integer on the heap and return the address. The only way you can do something sensible with the allocated memory, is save the address this gives you. The way you do this, is store it in a pointer:
int* heapPtr = new int;
and now you can use the pointer to access the memory:
*heapPtr = 3;
cout << heapPtr; // Will print the address of the allocated integer
cout << *heapPtr; // Will print the value at the address, i.e. 3
The thing is that variables created on the heap will keep on living, until you say you don't need them anymore. You do that by calling delete on the address you want to delete. E.g. if new gave you 0x12345678 that memory will be yours until you call delete 0x12345678. So before you exit your scope, you need to call
delete heapPtr;
and you will tell your system that the address 0x12345678 is available again for the next code that comes along and needs space on the heap.
Leaking memory
Now there is a danger here, and that is, that you may lose the handle. For example, consider the following:
void f() {
int* p = new int;
}
int main() {
f();
cout << "Uh oh...";
}
The function f creates a new integer on the heap. However, the pointer p in which you store the address is a local variable which is destroyed as soon as f exits. Once you are back in the main function, you suddenly have no idea anymore where the integer you allocated was living, so you have no way to call delete on it anymore. This means that - at least for the duration of your program - you will have memory that according to your operating system is occupied, so you cannot use it for anything else. If you do this too often, you may run out of memory even though you can't access any of it.
This is one of the errors you are making:
int* p = new int;
allocates a new integer on the heap and stores the address in p, but in the next line
p = &num;
you overwrite that with another address. At this point you lose track of the integer on the heap and you have created a memory leak.
Freeing memory
Aside from freeing memory not often enough (i.e. not instead of once), the other error you can make is freeing it too often. Or, to be more precise, you can make the error of accessing memory after you have told your OS you don't need it anymore. For example, consider the following:
int main() {
int* p = new int;
*p = 10;
delete p; // OK!
*p = 3; // Errr...
}
That last line is very wrong! You have just returned the memory allocated when you called delete, but the address is still stored in p. After you call delete, your OS is allowed to re-allocate the memory at any time - for example, immediately after another thread could call new double and get the same address. At that point, if you write *p = 3 you are therefore writing to memory that is no longer yours which may lead to disaster, if you happen to overwrite the location in memory where the nuke's launch codes are stored, or nothing may happen at all because the memory is never used for anything else before your program ends.
Always release your own memory, and nothing but your own memory
We have concluded the following: memory allocated on the stack is not yours to claim, and not yours to release. Memory allocated on the heap is yours to claim, but you must also release it once and only once.
The following examples are incorrect:
{
int a = 3;
int* p = &a;
delete a;
} // Uh oh... cannot clean up a because it is not ours anymore!
{
int* p = new int;
delete p;
*p = 3; // Uh oh, cannot touch this memory anymore!
delete p; // Uh oh, cannot touch this memory anymore!
}
Why does it print 10?
Well, to be honest, you were just "lucky" there. Actually, the way your operating system manages memory, is generally pretty lazy. When you tell it "I would like some memory" it doesn't zero it for you. That is why it is a bad idea to write
int main() {
int a;
a = a + 3;
cout << a;
}
You get allocated a variable a somewhere in the memory, but the value of a will be whatever was in that memory location. It might be zero, or some random number that depends on how the bits fell when you booted your computer. That is why you should always initialize the variable:
int a = 0;
Similarly, when you say "I don't need this memory" anymore, the OS doesn't zero it. That would be slow and unnecessary: all it needs to do is mark the memory as "free to be re-allocated". So if you give it back and access it immediately afterwards, the probability that it has not been re-allocated yet is pretty large. Therefore
int* p = new int;
*p = 10;
delete p;
cout << *p;
is not guaranteed to print 10. The address p is pointing to may have been (partially) taken (and initialized!) by someone else immediately after the delete. But if it hasn't, the memory will still contain the value 10 there so even though it isn't yours anymore, C++ will still allow you to access it. Basically, when you are using pointers, you are telling it "trust me, I'm a programmer - you don't need to do all kinds of slow checks to make sure I'm staying where I'm supposed to be, instead I'll be careful about that myself!"
using namespace std;
int main(){
int num = 10; // a) an int is created on stack
int *p = new int; // b) another int is allocated on heap
p = &num; // c) address of int from stack is assigned to p and the pointer
// allocated in b) is leaked: as nothing points to it anymore,
// it can't be deleted
cout << *p << endl;
delete p; // d) deleting a pointer that was not dynamically allocated
// and is pointing to stack.
cout << num << endl;
return 0;
}

I have some confusions on pointer deletion and assigning pointer into class

First of all, i had some confusion on pointer deletion. When i delete pointer a, i don't understand why int x is also deleted.. because i already assign a = f(which is the pointer pointing to y)
int x = 5;
int y = 3;
int *a = &x;
int *f = &y;
a = f;
delete a;
cout << x; // Segmentation fault (core dumped)
Second, if i want to assign value to a class with a char * pointer. How can i do?
class Foo{
public:
char * name;
void setName(char * const newName){
name = newName;
}
};
void getInput()
{
char temp[5];
Foo s;
char * x = new char[5]; // four words
cin >> temp;
strcpy(x,temp);
s.setName(x); // should i delete x pointer
// afterward because this function
// is going to terminated ?
}
You can only delete something that has been allocated with new. In your case, you are trying to delete something else, so you get undefined behaviour.
If you want your Foo class to "take ownership" of the pointer and be responsible for deleting it, then you should delete name in the class destructor.
Although a is a pointer, you can't delete it. It points to a memory block on the stack (not heap), it cannot be delete-ed.
The 'delete' operator is used to free up user-allocated space on the heap when you no longer have use of it. All allocated memory will be delete-ed once your application has ended automatically.
But... say you have a service that runs in the background in an endless loop and you allocate a space on the heap without delete it -> this allocated memory will most likely not be delete-ed (depends on the OS and type of pointer - volatile or not). It is in the developer's responsibility to make sure all allocated memory is delete-ed once his/her object is no longer in use (end of block or in the destructor).

Placement new for block of pointers

i am trying to allocate pointers of the first order one by one at memory.
Pointer of the second order must walk through this queue and handle to objects, created on that pointers.
Placement new works fine when i allocate the queue of objects(not pointers to them), but when i am trying the same with pointers the trouble happens.
int* p;
p = new int(1);
printf("%p - %d\n", p, *p); // address of int and its value
delete p;
First object is created and deleted to initialize pointer with some address, next objects will be created in cycle
p = new(p) int(2); // (p) - memory will be allocated at address
// on which p points
printf("%p - %d\n", p, *p); // address of int and its value
delete p;
p++;
p = new(p) int(3); // (p) - memory will be allocated at address
// on which p points
printf("%p - %d\n", p, *p); // address of int and its value
delete p;
Output:
01C1FFD0 - 1
01C1FFD0 - 2
01C1FFD4 - 3;
int** pp;
pp = new int*;
printf("%p\n", pp); // address of int*
*pp = new int(1);
printf("%p - %d\n", *pp, **pp); // address of int and its value
delete *pp;
delete pp;
pp = new(pp) int*;
printf("%p\n", pp); // address of int*
*pp = new int(2);
printf("%p - %d\n", *pp, **pp); // address of int and its value
delete *pp;
delete pp;
pp++;
pp = new(pp) int*;
printf("%p\n", pp); // address of int*
*pp = new int(3);
printf("%p - %d\n", *pp, **pp); // address of int and its value
delete *pp;
delete pp;
If int is not created by *pp then if pp is incremented it is not real to delete pp later,
if int is created by *pp then there is something strange with addresses and second value.
Output:
01C1FFD0
01C1FFE0 - 1
01C1FFD0
01C1FFD0 - 29491152
01C1FFD4
01C1FFD0 - 3
I would be very grateful for advice how to organize this queue correct.
p = new(p) int(2); // (p) - memory will be allocated at address
// on which p points
This is where you're wrong for the first time. new(p) T does not allocate any memory. Rather than that, it just creates a T at address p, assuming that p points to some memory where a T can be constructed. Also, since there is no memory allocated, you cannot just pass such pointers to delete, as this will attempt to release the not allocated storage. Rather than that, you need to manually invoke the destructor and dispose of the memory depending on however you acquired it.
Placement new is a rather advanced concept that you very likely do not need at this time. In fact, even "simple" manual memory/object lifetime management is something you probably should not be bothering yourself with at this time of your learning. What book are you learning C++ from? Have you seen this book list?
FYI: I haven't looked at your code below that line.

Pointer Memory Leak

My pointer p is inside a function, will i get memory leak with this code.
for(k=0;k< 3;k++)
{
int *p=NULL;
int val = bBreak[k+1] - bBreak[k];
p = new int [val+1];
p = &buff[bBreak[k]];
for(int i=0;i< val;i++)
{
cout<<"\n"<<p[i]<<endl;
}
}
Yes! You never free the memory. You should call delete/delete[] for every piece of memory you allocate with new/new[].
Yes, you will
p = new int [val+1]; //allocate array on the heap
p = &buff[bBreak[k]]; //new allocated array is leaked because you lost the pointer to it
//and you are not able to call 'delete[]' to free the memory
Generally, every call to operator new should be paired with call of operator delete or delete[]
Yes. You must delete every memory you allocate with new.
p = new int [val+1];
p = &buff[bBreak[k]]; // here you lose track of the memory you've just allocated
If you don't want to do memory management by-hand, use a std::vector<int>.