Can someone help me with this question?
The memory allocated on line (*) below is not deleted.
void f() {
int z = *new int; // (*)
//...
}
Without changing the code on line (*), is there any way to avoid leaking memory? If so, how? If not, why not?
What I don't understand is, what does *new int mean? Specifically, what does adding the * beside new mean?
Also, what if instead of int z, we have int &z?
That line is the memory leak. It also makes no sense what so ever allocating an int int on heap and derefencing it (with *) before saving it's handle (address returned by new). So the only posible way to avoid the leak is:
return;
// your silly * line here
Without changing the code on line (*), is there any way to avoid leaking memory?
In real life, you would absolutely change that line - it's insane.
Assuming this is an intellectual exercise, then possibilities are:
Add return; before it, so the new never happens;
Override ::operator new to return a pointer that you can access by other means, such as a global variable.
What I don't understand is, what does *new int mean?
new int dynamically allocates an object of type int, and gives a pointer to that. * dereferences that pointer so that the object can be copied to initialise z. The pointer is not stored anywhere, so there is no way to access or delete the dynamic object afterwards.
Also, the initialisation of z from the value of an uninitialised object gives undefined behaviour.
Also, what if instead of int z, we have int &z?
z would be a reference to, rather than a copy of, the dynamic object. It would then be possible to fix the leak with delete &z. That would be an unidiomatic, confusing thing to do; don't do it in real code.
In general, avoid dynamic allocation and, when it is necessary, manage dynamic resources with RAII types, like containers and smart pointers. Raw pointers are error-prone, expecially when exceptions are thrown; anything else is a recipe for insanity.
That to understand this statement
int z = *new int; // (*)
it will be useful to split it logically.
At first there is called operator
new int
Take into account that the memory allocated by this call will not be initialized.
The result of the execution of the statement is some temporary pointer to int that is int *
Let;s name it as p.
In the next step this temporary pointer is dereferenced
*p
and this expression returns some garbage that the allocated memory has.
And this garbage are assigned to variable z.
So the code has no any sense.
At least it would be better to write something as
int z = *new int( 10 );
or
int z = *new int();
or
int z = *new int {};
that to initialize variavle z
Nevertheless in any case there will be memory leak.
The only method that I see to escape the memory leak is to write
int z = *std::unique_ptr<int>( new int() );
No, there's no way to not leak memory with that code, since the pointer returned by new is lost.
*new int means "allocate memory for an int, resulting in a pointer to that memory, then dereference the pointer, yielding the (uninitialized) int itself". I think this is undefined behavior.
Related
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.
Let's say you have a function
int * something ( int size ){
int * sample= new int[size];
//... do something
return sample;
}
Then if using it somewhere else like
...
Int * temp=something(5);
// use the array....
delete [] temp;
....
Is this gonna cause mem leak??
It is legal but quite error-prone because there's risk of memory leak if there's an exception between the array being allocated and the same array being deallocated. Better use smart pointers to make this code exception-safe.
Yes, you can delete[] what was new[]ed earlier as long as you use the same type pointer and as long as the pointer still points onto the same address and the array was not yet deallocated elsewhere in your code (so-called "double free" problem). All three requirements must be met, otherwise you run into undefined behavior and then all bets are off.
I have the following below code snippet
class test{
private:
int *ptr;
public:
test(int *myptr){
ptr = myptr;
}
~test(){
delete ptr;
}
};
int main(){
int* myptr = new int;
*myptr = 10;
test obj(myptr);
delete myptr;
}
Is there a memory leak happening in this program, if I dont do a new to pointer in the class will space be allocated for that pointer?
Rule of thumb for dealing with allocating member: every new/new[] should be paired with exactly one delete/delete[]. If you are missing the delete, then you have a memory leak (you have allocated memory that you never clean up). If you are delete-ing multiples times, as you are doing in this code example, you will have memory corruption issues.
How are you delete-ing multiple times? In main(), you allocate a pointer:
int* myptr = new int;
You give a copy of that pointer to your test object, obj. Then, at the end of the scope we have:
{
// ...
delete myptr;
~test(); // implicit, which also does delete myptr
}
Only one of those two places should be responsible for delete-ing the pointer. Which one is based on the semantics of your code. Does test own the pointer? In which case, it should delete it but main() should not. Does it simply observe the pointer? In which case, it should not delete it. With C++11, we have new smart pointers to express this idea better.
I'd encourage you to browse the definitive C++ book list as concepts like this are very crucial to understanding C++ but also very difficult to explain properly in a short Q&A format.
You should only delte a pointer once in ~test() or delete directly
*** Error in `./a.out': double free or corruption (fasttop): 0x08d13a10 ***
Consider using std::shared_ptr<int> or std::unique_ptr<int>, since direct memory management is discouraged in modern C++ unless you've a reason to do so.
You can read about semantics differences of smart pointers here, and the reference for them is here.
It will crash when exit main function, a allocated in heap memory can't be release two times
What will happen in your instance is that the pointer will be given to delete in main(), then the same pointer value will be given a second time to delete in the destructor of obj. This is undefined behaviour, so it might work, or it might not, in any case, it isn't guaranteed to work, and therefore such a construct should not be used.
Ordinarily you would establish ownership rules, e.g. whether the constructor “takes ownership” (and is therefore responsible for freeing resources) is up to you, but typically, and especially in modern C++, ownership semantics can be clearly achieved by using std::unique_ptr and std::shared_ptr.
Most importantly, whichever method you use to determine ownership, make sure you are consistent! Avoid complicated ownership semantics, as it will make it much more difficult to detect memory-related issues (or more generally, resource-related issues).
Contrary to what other people have said: you do not delete pointers in C++, but objects.
What's the difference?
Let's simplify your code a bit:
int *myptr = new int; // 1
int *ptr = myptr; // 2
delete myptr; // 3
delete ptr; // 4
As far as the usage of new and delete is concerned, this is the same code - I've just removed the class, since it's not relevant to the point here.
This code does the following:
new int allocates an int, and returns its address. The address is then stored in myptr.
The address is copied to ptr. Both ptr and myptr contain the address of the int that was just allocated.
The int is deallocated.
The int is deallocated... but it was already deallocated? Oops!
If you're lucky, your program will crash at this point.
delete myptr; has nothing to do with the variable myptr, except that myptr holds the address of the thing to delete.
It doesn't even have to be a variable - you could do delete new int; (although it wouldn't be very useful) or delete someFunctionThatReturnsAnAddress();, or int *p = 1 + new int[2]; delete [] (p - 1);.
Your class has only a reference of the allocated integer. Consider to declare it int const* ptr, then you cant delete it inside the class.
You should remove delete ptr from the destructor.
Usually the scope which is allocating something is responsible for freeing it. In your case the main routine is allocating and has to free.
For your question "Is there a memory leak happening in this program", the answer is No, but an exception is rasing.
Your code logic is not good, you should delete the pointer at where it was created. In this example, you shouldn't delete ptr in destructor function.
If I go...
int *foo = new int;
foo += 1;
delete foo;
Most of the time it crashes. Is there a reason for this? I'm trying to have the pointer point one spot forward (4 bytes). Thanks.
Edit (six months later): This was the first question I asked on SO, and it was a silly question and deserved the downvotes. It can be deleted if it's of no use to learners. I was indeed talking about allocating an int of four bytes on the heap, then moving the pointer four bytes forward, and then deleting the int pointer, essentially deleting God knows what, leading to undefined behaviour. Thanks for your help.
The only thing you can safely pass to delete is something you got when you called new, or nullptr, in that case the delete won't do anything.
You changed the value of the pointer - therefore it isn't "something you got when you called new"
You must pass to delete the value that new returned. You don't do that.
I think that you are confused as to what you are passing to delete. I think that you believe that delete foo will delete the memory associated with the variable. It doesn't. It deletes the memory whose address is stored in foo.
As an example, this is legitimate:
int* foo = new int;
int* bar = foo;
delete bar;
What matters is not the name of the variable, but rather the value of the variable.
Here's another example:
int* arr = new int[10];
int* ptr = arr;
for (int i; i < 10; i++)
{
*ptr = i;
ptr++;
}
delete[] arr;
In order to perform pointer arithmetic, and retain the address returned by new[], we introduced an extra variable. I used an array because it doesn't make sense to perform arithmetic on a pointer to a single value.
Note that in the code above, it could be written more clearly using arr[i] = i and so avoid the need for a second pointer variable. I wrote it as above to illustrate how you might code when pointer arithmetic is the right option.
In many tutorials, the first code samples about dynamic memory start along the lines of:
int * pointer;
pointer = new int; // version 1
//OR
pointer = new int [20]; // version 2
They always proceed to explain how the second version works, but totally avoid talking about the first version.
What I want to know is, what does pointer = new int create? What can I do with it? What does it mean? Every tutorial without fail will avoid talking about the first version entirely. All I've found out (through messing about) is this:
#include <iostream>
using namespace std;
int main()
{
int * pointer;
pointer = new int;
pointer[2] = 1932; // pointer [2] exists? and i can assign to it?!
cout << pointer[2] << endl; // ... and access it successfully?!
};
The fact that I can subscript pointer tells me so far that pointer = new int implicitly creates an array. But if so, then what size is it?
If someone could help clear this all up for me, I'd be grateful...
My teacher explained it like this.
Think of cinema. The actual seats are memory allocations and the ticket you get are the pointers.
int * pointer = new int;
This would be a cinema with one seat, and pointer would be the ticket to that seat
pointer = new int [20]
This would be a cinema with 20 seats and pointer would be the ticket to the first seat. pointer[1] would be the ticket to the second seat and pointer[19] would be the ticket to the last seat.
When you do int* pointer = new int; and then access pointer[2] you're letting someone sit in the aisle, meaning undefined behaviour
This is a typical error in C and C++ for beginners. The first sentence, creates a space for holding just an int. The second one creates a space for holding 20 of those ints. In both cases, however, it assigns the address of the beginning of the dynamically-reserved area to the pointer variable.
To add to the confusion, you can access pointers with indices (as you put pointer[2]) even when the memory they're pointing is not valid. In the case of:
int* pointer = new int;
you can access pointer[2], but you'd have an undefined behavior. Note that you have to check that these accesses don't actually occur, and the compiler can do usually little in preventing this type of errors.
This creates only one integer.
pointer = new int; // version 1
This creates 20 integers.
pointer = new int [20] // version 2
The below is invalid, since pointer[2] translates as *(pointer + 2) ; which is not been created/allocated.
int main()
{
int * pointer;
pointer = new int;
pointer[2] = 1932; // pointer [2] exists? and i can assign to it?!
cout << pointer[2] << endl; // ... and access it succesfuly?!
};
Cheers!
new int[20] allocates memory for an integer array of size 20, and returns a pointer to it.
new int simply allocates memory for one integer, and returns a pointer to it. Implicitly, that is the same as new int[1].
You can dereference (i.e. use *p) on both pointers, but you should only use p[i] on the pointer returned by the new int[20].
p[0] will still work on both, but you might mess up and put a wrong index by accident.
Update: Another difference is that you must use delete[] for the array, and delete for the integer.
pointer = new int allocates enough memory on the heap to store one int.
pointer = new int [20] allocates memory to store 20 ints.
Both calls return a pointer to the newly allocated memory.
Note: Do not rely on the allocated memory being initialized, it may contain random values.
pointer = new int; allocates an integer and stores it's address in pointer. pointer[2] is a synonym for pointer + 2. To understand it, read about pointer arithmetic. This line is actually undefined behavior, because you are accessing memory that you did not previously allocate, and it works because you got lucky.
int* p = new int allocates memory for one integer. It does not implictly create an array. The way you are accessing the pointer using p[2] will cause the undefined behavior as you are writing to an invalid memory location. You can create an array only if you use new[] syntax. In such a case you need to release the memory using delete[]. If you have allocated memory using new then it means you are creating a single object and you need to release the memory using delete.
*"The fact that i can subscript pointer tells me so far that I pointer = new int implicitly creates an array. but if so, then what size is it?"
*
This was the part of the question which I liked the most and which you emphasize upon.
As we all know dynamic memory allocation makes use of the space on the Stack which is specific to the given program.
When we take a closer look onto the definition of new operator :-
void* operator new[] (std::size_t size) throw (std::bad_alloc);
This actually represents an array of objects of that particular size and if this is successful, then it automatically Constructs each of the Objects in the array. Thus we are free to use the objects within the bound of the size because it has already been initialized/constructed.
int * pointer = new int;
On the other hand for the above example there's every possibility of an undefined behaviour when any of
*(pointer + k) or *(k + pointer)
are used. Though the particular memory location can be accessed with the use of pointers, there's no guarantee because the particular Object for the same was not created nor constructed.This can be thought of as a space which was not allocated on the Stack for the particular program.
Hope this helps.
It does not create array. It creates a single integer and returns the pointer to that integer. When you write pointer[2] you refer to a memory which you have not allocated. You need to be carefull and not to do this. That memory can be edited from the external program which you, I belive, don't want.
int * pointer; pointer = new int; // version 1
//OR
pointer = new int [20] // version 2
what I want to know is, what does pointer = new int create? what can I do with it? what does it mean? Every tutorial without fail will avoid talking about the first version entirely
The reason the tutorial doesn't rell you what to do with it is that it really is totally useless! It allocates a single int and gives you a pointer to that.
The problem is that if you want an int, why don't you just declare one?
int i;