Calling delete on address of variable - c++

Why can I do:
int i = *(new int (5));
and successfuly use i after it,
but when I'm trying:
delete &i;
I get a run time error:
Unhandled exception at 0x5ddccaf7 (msvcr100d.dll) in Test.exe:
0xC00000FD: Stack overflow.
If i was a reference:
int & i = *(new int (5));
, all this (including delete) works fine.
I know, that it's no good to keep allocated memory handler in something other than pointer and *(new ...) is awful, but I'm just wondering, why new works good, but delete fails.
//Below are just my guesses about the reason of such behavior:
Is it because module which executes program (it's probably not "compiler", because of there is run time already) when it encounters with delete, it searches for some information like length of data pointing by &i (in some internal array of such information about all pointers) and don't find it or interpretes some trash data as this information? (I suppose, pointers and references have it, but variables don't)

Your original version does not assign i to an address. It allocates a new int on the heap and initializes its value to 5, then copies that value into i which is on the stack. The memory that you allocated (new'ed) is inaccessible and gets leaked.
The reference version works because i refers to the otherwise-anonymous new'ed memory. Hence &i gives the heap address. In your first version, &i gives the address of the stack variable, not the heap memory, and deleting stack memory is bad news.

You get a run-time error because the address of i is not the same as the address returned by the operator new. Once you dereference the result of new, you make a copy of the value. That copy is then placed into variable i, which has an address in automatic storage, which cannot be passed to delete legally without triggering undefined behavior.
When you make a reference, however, you do not make a copy: the result of new becomes referenced through a variable i of type "reference to int". Hence, the reference has the same address as has been returned by operator new, so the code that uses the reference works fine.

The line:
int i = *(new int (5));
Is equivalent to:
int* p = new int(5);
int i = *p;
The address of i (which you are trying to delete) is not the address of the allocated memory.
In mathematical notation, &x == &y implies x == y, but x == ydoes not imply &x == &y.

Related

c++ pointer segfaults without compiler warning, works when previously assigned

I have a difficulties understanding pointers and how/when they fail. So I made a tiny program which creates a pointer, assigns a value to it and then prints that value. Compiles fine with both gcc and clang and does not give any warnings when using the -Wall switch. Why does it segfault and why does it not segfault when I assign a different value to the pointer first? I thought I had initialized the pointer to somewhere. When I just declare the pointer without initialization, then I rightfully get a compiler warning. However, here I do not get a compiler warning, but it still segfaults.
#include<iostream>
int main(){
int *b = (int*) 12; //pointer gets initialized, so it points to somewhere
//int a = 13; //works fine when uncommenting this and the next line
//b = &a;
*b = 11;
std::cout << "*b = " << *b << "\n";
return 0;
}
A pointer is a variable that save a memory address.
You "can" have any memory address in your pointer, but trying to read from memory space outside of where your application are allowed to read, will trigger the OS to kill you application with a segfault error.
If you allow me the metaphor:
You can write on a paper the address of any person in your country. But if you try to enter that house without permission, you most probably will get stopped by the police.
Back to code:
int *b = (int*) 123; // ok, you can save what you want.
std::cout << *b << std::endl; // SEGFAULT: you are not allowed to read at 123.
When you uncomment the two lines of code:
int a = 13;
b = &a;
Basically, b is not any-more pointing to that forbidden 123 address, but to the address of a. a is in your own code, and it memory is not forbidden to you, so accessing *b after this is allowed.
Reading at any hard-coded address is not forbidden by C++ (in fact it is useful in some situations), but your OS may not allow you to mess with that memory.
On the other hand, the compiler is able to detect a variable being used without initialization, and can warn this case. This has nothing to do with raw pointers.
A pointer is a variable to store an address.
int *b = (int*) 12;
This declares b as a pointer to a value of type int, and initializes it with the address 12. Do you know what resides at address 12? No, you don't. Thus, you should not use that address.
*b = 11;
This stores an integer 11 at the address pointed to by the pointer b. However, since pointer b points at address 12, the integer 11 overwrites something at that address (we don't even know what does it overwrite, because we don't know what is there to begin with). This could corrupt heap or stack or program's code or just cause an access violation, anything can happen.
But if you first do this:
b = &a;
Then pointer b now points at the address at which the variable a is stored. Thus, subsequently writing 11 at that address will just overwrite a's value (from 13 to 11), a perfectly valid operation, no problems.
I just need it to point to some location that can hold an int
Indeed, but this is not enough. Not only shall the location be able to hold an int, that location must also be available for your program to store such an int. This means the location needs to be either that of an existing object (e.g., of an existing variable of type int) or a newly allocated memory chunk capable of holding an int. For example:
b = new int;
This will dynamically allocate the memory needed to store an int, and assign the address of the newly allocated memory to the pointer b.
Remember that after you're done with such dynamically allocated memory, you should deallocate it:
delete b;
Otherwise, there will be a memory leak (at least until the whole process exits anyway).
Nowadays, in modern C++, there is rarely a need to use raw pointers to manage dynamic memory allocations/deallocations manually. You'd use standard containers and/or smart pointers for that purpose instead.

C++ raw pointers and "delete"

I have a question regarding the code snippet below:
double d = 20.1;
double* pd = new double;
...
pd = &d;
delete pd;
The last line throws an error in Visual C++ 2015. Does this mean that the pointer "pd" points to the stack address of "d" and its original pointed-to address in the heap (right-hand side of the equal sign in the second line) has leaked?
Yes, you leaked the double originally pointer by pd, but that's not what's causing the error.
The error is a result of you trying to delete a stack allocated address. That is is strictly undefined behavior. delete will only work for pointers which were created with new.
Variables hold values. Pointer values are just that, values. Not names. Not variables.
When you manipulate a pointer value, for example to pass it to delete, you only care about the value.
It's essentially equivalent to:
int one=1;
one=2;
std::cout << one; // you won't be surprised to see 2, will you?
The value currently in the variable matters; not some previous value. Not the name.
Your program tries to deallocate (delete) an object that wasn't allocated by you (the user), but by the compiler.
Does this mean that the pointer "pd" points to the stack address of "d" and its original pointed-to address in the heap (right-hand side of the equal sign in the second line) has leaked?
Yes, that is exactly what this means.

pointers scope questions and return reference of pointer inside vector of pointers encapsulated in class

I have some questions about pointers, scopes and pointers inside vector encapsulated in class
i have this supposed cases and examples with questions:
Example 1
the variable int y scope is inside the function and when the function finish and go away that returning reference will be died and that reference be referenced to nothing?
int& createInt() {
int y = 5;
return y;
}
case1: if i do this in main or other function:
int x = createInt();
std::cout << "x value \n";
std::cout << x << "\n";
// std::cout return 5
this mean that im saving my own copy of the value of createInt()
function that is 5 in the variable x, so is safe because int x contain their own value?
but what happen with the reference returning from the createInt() function, is there a memory leak or not because is not a pointer a will die with the scope of the function.
case 2: if i do this in main or other function:
int &x = createInt();
std::cout << "x value \n";
std::cout << x << "\n";
// std::cout return 32767
int &x is equals to the reference returning from createInt() function, that reference die when the function finish/go away so for that reason
int &x is returning a wrong value 32767 and not 5 or what are that 32767 value?
so int &x = createInt(); is evil and very bad practice because is reference to nothing.
example 2
what about this? i'm requesting allocation memory for int and initialized memory to the pointer variable...
int& createInt() {
int* y = new int(5);
return *y;
}
that pointer variable is in the stack but store a reference to the new int that is in the heap, so that new int will be alive when the scope of the function go away because is in the heap right?
so when i return the reference i'm returning the reference to that new int not the pointer variable, right? so is bad to returning the reference instead of the pointer? for what?
case1: if i do this in main or other function:
int x = createInt();
std::cout << "x value \n";
std::cout << x << "\n";
// std::cout return 5
i'm creating a copy of the new int value from createInt() in my local int x variable, so is this a memory leak because i'm creating a copy and not getting the pointer, so i can't do a delete of int x variable because is not a pointer, and also i can't delete the int *y pointer created inside createInt() function because the pointer is lost, i don't have it outside the createInt()
but whats happen if i do:
delete &x;
i will get a error:
malloc: *** error for object 0x7ffee204b8c8: pointer being freed was not allocated
because i'm deleting my int x that is not in the heap? or is trying to delete the int *y inside the createInt() function ?
case2: if i do this with the same function:
int &x = createInt2();
std::cout << "x value \n";
std::cout << x << "\n";
// std::cout return 5
my int &x is a reference of the returning by createInt()
so i can do:
delete &x;
is a memory leak here? but its so bad delete &x reference instead of the pointer int *y? maybe doing delete & i'm not have form to be sure if that is allocated memory or is stack memory, so good practice is never try to delete using &?
vectors parts:
i have a class A that contain a vector of pointers of class B, also i have a method that return a element of the vector but as reference (because i want to have it in memory to reutilize it and control when is deleted like a connection pool also i move it from used vector to notInUsevector but this is other history), and in the destructor of class A i delete all the vector elements:
Class A {
//this is singleton
public:
static A& getInstance()
{
std::call_once(m_once, []() {
instance.reset(new Database());
});
return *instance;
}
B& getFirstElement() {
auto element = connections.front();
return *element;
}
~A() {
for(auto element : myVector){
delete num;
}
}
A(A const &) = delete;
void operator=(A const &) = delete;
private:
A();
static std::unique_ptr<A> instance;
static std::once_flag m_once;
std::vector<B*> myVector;
}
so in other place/function/class etc i do:
auto element = &A::getInstance().getFirstElement();
or maybe is best or the same:
auto &element = A::getInstance().getFirstElement();
so when the Class A instance is deleted the destructor will delete all the pointers inside myVector
is this safe, there is a memory leak? it's a very bad return the reference in the getInstance() function instead of the pointer?
thanks
First of all let's make it clear, scope is "layer" between { and }. It might be a function body, statement (if, switch, for, etc.) or standalone scope. The most important consequence is that life time of objects created on stack is limited to that scope.
Take your function createInt() as example, internal int y, exists only inside of that function. The moment you reach } that memory is free.
Second thing is term memory leak. Memory leak is a situation where you have a chunk of memory (might be a single byte, might be a couple of pages) and no way to point at it. It's like a locked box without a key. It is there, it is yours memory, it won't be free unless you tell, problem is you don't know where that memory is located, you have no pointer for it.
That's being said, let's talk about your cases:
Example 1 Case 1:
You are lucky. Your function return its internal y by reference, but this returned variable is freed before you return from your function. Effectively you have a value written down on sticky note, then you throw it to the trash and then return saying that your value is on that note that is in trash. The only reason you can still read it is because no one assigned that bit of memory in the mean time and it was not overwritten. Remember, the moment your function reached } all stack alocated variables (y was allocated on stack) are destroyed. That also answer your second question about memory leak, there is no memory leak. As long as you work with stack, allocation and deallocation is done "automagically" as destructor calls are inserted at the end of the scope (usually) by compiler.
Example 1 Case 2:
The very same thing as in case 1. Your returned value is compromised because you returned stack allocated variable that is no longer valid as you return from function. Now you can observe this because between assigning and reading that value you make a function call. Depending on where original y was allocated that bit of memory might be reused during std::cout call. This become obvious as you work on the very same bit of memory cause of reference usage. Remember when you reached } of createInt(), you free that bit of memory. As an additional excersise, put a break point on lines int &x = createInt(); and int x = createInt(); then step into function and watch memory state as you leave it.
Example 2 Case 1:
Now you create (potential) memory leak. You allocate a memory on heap so it won't be destroyed as you leave function body. You also pass that exact memory address, so you also should take responsibility for freeing it and you don't call delete, so that's your memory leak. And one more problem occurs as you assign returned value to completely new stack allocated variable. Your original x from createInt() is allocated, then returned by reference but feed to assign operator to other independent variable (int x have different address than int* y). Again you can check this with help of breakpoints and debugger.
Example 2 Case 2:
Now this is almost proper use of variables returned by reference and assignment of them. You create variable x on heap, then return it's address and assign it to y. Problem being as x was created on stack you are responsible for destroying it so call to delete is neccessary to avoid memory leak. Put a break point and track memory addresses of both x and y. They are the same.
General rule of thumb is that return by reference should be used only with variables that exist outside of function, for example you can use it for class memebrs as they live inside the object or for global or static variables. For other purposes use return by value, unless you really need that very object, then return it by pointer. And while you work with pointers always be aware that someone at some point have to delete underlying variable.
I skip the part about vectors and instead point you a good tool for tracking memory leaks. It's not the best solution by any means, but for starters it will do the trick (assuming you are using Visual Studio).
https://learn.microsoft.com/pl-pl/visualstudio/debugger/finding-memory-leaks-using-the-crt-library?view=vs-2019
Remember to use breakpoints and debugger instead of printing everything to output/console. This will help you a lot. In both tracking memory and variable state, and understanding what your code really does.
I don't have the impression you have a real question at all, because you seem yo have found out all tricks, traps and good practices on your own. You seem to know about memory leaks and dangling references. Static and dynamic allocation. Most of your assumptions seem correct. Some hints though :
* references '&' and raw pointers result in exactly the same machine instructions, but they are hints to the programmers. Indeed, a method returning a reference likely means you don't have to take ownership for that reference, but without documentation there is no guarantee on the lifetime of that object. A raw pointer may represent a heap instance, or an optional argument, but it could also represent just a reference. This lack of ownership rules in C/C++ is indeed tricky.
* When dereferencing a dangling reference, the behavior is undefined. It may be working perfectly on your machine and it could burn my harddisk. Anything goes.
* When dealing with heap allocations, we nowadays prefer yo use smart pointers whenever possible. There is no mistaking in it's usage. Search for unique_ptr and shared_ptr
* Finally I recomy learning a bit of Rust. This is a programming language that was specifically designed to resolve such object lifetime/ownership issues. It is quite easy to install and run the most basic examples. Just try returning a dangling reference with Rust, you'll learn a lot, believe me.

C++ Pointer and Memory Allocation

I am teaching myself C++. It is my first programming language and I am struggling with the wording associated with the memory allocation of pointers.
Consider this statement:
int *p;
int x;
p = &x;
*p = 8;
Value
&p 1400
p 1800
*p 8
x 8
&p is the memory address of p.
p is the memory address pointed to by the pointer p.
*p is the value of the memory address pointed to by the pointer p.
I understand this. However the book states:
p = &x stores the address of x in p. However, no new memory is allocated.
This is confusing. Memory has been allocated, else p would be undefined.
Now consider this statement:
int *p;
p = new int;
*p = 28;
Here, you dont need an additional variable to make *p valid and meaningful, because memory has been allocated.
So, I guess my question is:
What is the author's meaning of his statement, "Memory is not allocated.", when considering the code block?
p = &x stores the address of x in p. However, no new memory is allocated.
100% true. All of the allocation was done in the preceding two lines.
int *p; // allocation of p here
int x; //allocation of x here
p = &x; // no allocation here.
p = &x; is just an assignment of the location of previously allocated memory to a previously allocated pointer. Whether storage is allocated on the stack, the heap, or whatever the current system uses instead of a stack or heap is irrelevant.
For the second example,
int *p; //allocation of p here
p = new int; // allocation of one nameless int AND assignment of that int to p here
*p = 28; // no allocation
Generally the single word 'allocated' is used as an abbreviation for 'allocated out of heap storage using the 'new' keyword, a library routine such as 'malloc', or some other such mechanism (directly or indirectly)'.
Here the statement 'p = &x;' means that the value of p is set to the storage address of x, which is allocated on the stack. Since the stack storage is managed automatically rather than at the programmer's discretion, we choose not to refer to this as 'allocated' in colloquial usage.
Memory is allocated on the stack when you first declare the variable. Here, memory is allocated in
int *p;
int x;
So, p = &x; stores the memory address of x in the previously allocated memory for p on the stack.
"p = &x stores the address of x in p. However, no new memory is allocated."
I think this probably just means that in this particular statement p takes the address of x and no new memory is allocated for x. The memory for x was probably earlier allocated but initialization of p doesn't allocate new memory for x.
But in the latter statement
int *p;
p = new int;
*p = 28;
p points to a new chunk of memory that has been allocated because it is initialized with "new int".
"p = &x stores the address of x in p. However, no new memory is allocated." Because 'x' was created on the stack, not on the heap (just like the variable 'p', and all other 'local variables'). It seems your 2nd example is incorrect, but I'm not 100% sure.
Author probably refers to heap allocation. Both p and x are allocated on stack, which is really just incrementing (or decrementing, depending on machine type) the stack pointer. They're deallocated when they go out of scope. OTOH, new int allocates it from heap memory, which probably takes more time to do, but can live longer than it's scope: you manually deallocate it using delete. Either case, pointer works well: this might be non-evident at first, but you can take the address of a variable on the stack or one that's allocated from the heap using the same type.
Well I got that book and the explanation provided by others is correct. Just adding mine too.
When you compile a function, unless it is a variable argument one, the frame size and format is already known to compiler. Now when you call this function, compiler reserves the memory for this frame on the stack above (or below) the caller function. You can see this happening yourself.
void fun(){
int a,b;
printf("addr fun &a=%u, &b=%u",&a,&b);
callfun();
}
void callfun(){ int c;
printf("addr callfun &c=%u",&c);
}
On most architectures, address may seem decreasing - but logically by calling calllfun(), we created a frame above previous frame.
So, one can say that memory for these variables was created transparently and programmer never cared for that. When the stack grows, more memory is used, and freed when the function calls come closer to the main entry point function. But in other case, when you use new operator, programmer explicitly asks for memory in addition to what has been already allocated on the stack. This is fulfilled from another region in program's address space called heap. OS provides facility for doing this.
In your case, author just said that since the function carrying all these variables was already called, memory has already been allocated (on stack) in the process and NO NEW memory was created. However, you may use new operator to allocate more memory if you want.

Some basic pointer questions

I have a few silly questions (probably for most), it's less about 'how' do I do them and more about 'why' do they work this way? I know you are not supposed to ask multiple questions, but these are fairly small and related to one topic. Seems like it'd be a waste to separate them out.
I understand for the most part pointers, and the operators themselves. (Although I am curious why the * is called the de-reference operator, since isn't it referring to a reference of what it contains?)
I.e:
int x = 25;
int *p = &x;
So & makes sense, since *p is a place in the stack of type int that contains the address of x (which we know is 25).
So by saying *p are we 'referencing' the address of p which is pointing to the 25. Maybe it's just an English semantics thing? Maybe someone can explain why it's called 'de-reference'?
Take this valid code sample:
int *p = new int;
*p = 5
Simple enough, we're making a new place in the stack with the size of an int pointer (whatever that may be). p will contain some address that has a 5 for a value.
Thing is, I haven't actually declared anything that's storing a 5, so what the heck is p pointing to? I mean, this does indeed work, but I never made a int x = 5 or anything like that, and gave the address to p to point to? How does it even know?
p contains an address that points to something, but I never made that 'address' it's pointing to? Does the compiler just know to create another address somewhere else? (Sorry if this is a really stupid question.)
I was reading on here about some memory leaks on another question:
A *object1 = new A();
pretending A is a class first of all. Someone was saying the object1 stores the value of A. Isn't that incorrect? Doesn't object1 store the address of what new A() created and is pointing to it?
Because delete object1 deletes the pointer, which points to the new A() (but from the other question delete object1 would indeed be the correct syntax. So does that leave the new A() hanging out there? Or does it get automatically deleted? (As you can tell I'm a bit confused.)
If delete object1 does indeed delete what the pointer is pointing to and not the pointer itself, doesn't this just leave a dangling pointer?
Here
int x = 25;
int *p = &x;
* is not the dereferencing operator. It's part of the type of p. It basically says that p is a pointer.
Here
int *p = new int;
*p = 5;
The key is new int. It dynamically creates an int and returns it's address, so p now points to that address. *p = 5 (btw, here * is the dereferencing operator) modifies the value -- of that dymanically allocated int -- to 5
Indeed object1 holds the address of the newly created A. Since we're here we should clarify this: A is a (user defined) type. So it makes no sense to say that A has a value. Objects of type A have value.
delete p doesn't delete a pointer. It does 2 things:
Destroys an object created by a new-expression
Deallocates storage previously allocated by a matching operator new
The pointer isn't actually changed, i.e. it still points to the same address. Only now that address isn't allocated, i.e. can't be dereferenced anymore.
You can further refer to this SO answer - Static, automatic and dynamic storage duration to further understand objects, pointers, new/delete.
1: I'm not sure what you're implying when you say "which we know is 25". The address of x is not 25, rather that is the value of x. You do not set the address of x in a statment like int x = 25
But to answer your question, p is a reference, which is to say its value is an address. Accessing the value stored at the address p requires the *p, which dereferences the pointer.
2: You have allocated memory for p; you executed a new. You have allocated 4 (or 8) bytes of memory for a new integer on the heap, so p is pointing to a newly allocated block of memory. Saying *p = 5; tells the compiler to set the value stored at that address to 5.
3: Your assumption is correct; object1 does not store the value of a new A, rather points to a block of memory equivalent in size to aninstance of an object of size A.
delete object1; Does not delete the pointer. The pointer is simply an integer on the stack, rather it gives back the allocated memory for that pointer back to the system. A as you knew it is deleted, but the pointer still exists, and using it at this point is undefined behavior. You are correct in assuming you have a dangling pointer now, that is why you should always set deleted pointers to NULL.