This question already has answers here:
Calling delete on variable allocated on the stack
(12 answers)
Closed 9 years ago.
I am trying to understand how to delete a vector of pointers, and the pointed objects, in memory. I have started with a simple example, found in another thread, but I get "pointer being freed was not allocated" error.
What I am doing wrong?
#include <vector>
#include <algorithm>
#include <iostream>
int main(){
std::vector <int *> vec;
int a = 2;
int * b = &a;
int c = 3;
int * d = &c;
vec.push_back(b);
vec.push_back(d);
for (int i = 0; i < vec.size(); i++) {
delete vec[i];
}
vec.clear();
}
Only call delete on variables that were created with new
Check this link:
Calling delete on variable allocated on the stack
You're deallocating memory that was allocated on the stack with automatic storage. That's why you're getting errors.
Only delete things you allocated with new. RAII will take care of the rest.
When you do
int a = 2;
You are allocating a int on stack and anything on stack does not need to delete, it will be freed automatically once we left the scope it is declared. Therefore in your code, you are trying to free the same thing twice.
Whilst if you do
int* a = new int(2);
You will then allocate a int on heap, where data will not be deleted unless you explicitly call delete.
The bottom line is, new and delete should always be written in pairs.
Related
This question already has answers here:
What happens to the pointer itself after delete? [duplicate]
(3 answers)
Why doesn't delete set the pointer to NULL?
(12 answers)
Closed 2 years ago.
Please have a look at this below code::
#include<iostream>
using namespace std;
int main()
{
int *ptr;
ptr = new int[100000];
cout<<"\n\n address = "<<ptr;
for(long int i=0;i<100000;i++)
*(ptr+i) = i+1;
delete []ptr;
cout<<"\n\n address = "<<ptr;
ptr = new int[5];
cout<<"\n\n address = "<<ptr;
return 0;
}
OUTPUT is:
address = 0xd42490
address = 0xd42490
address = 0xe919d0
Why,After delete []ptr; it is still pointing to its previous location(See the 2nd output).
delete[] is working just as it should. It ensures that destructors are called for the members of the array and marks the memory (internally) as available for re-use.
There's nothing in the C++ standard that says it has to zero the memory or return the memory to the OS or clear the variable holding the address you passed to it, etc.
Once you delete something, you know destructors have run and you also know that you are no longer allowed to look at (access) that memory. If you do anyway, there's no guarantee what you'll get (except UB).
A pointer is just like a cardboard sign saying "there's something over there". When you use delete on the pointer it destroys what's "over there", but it doesn't re-write the sign itself (the pointer), so the pointer still points to the same memory location it always did, but accessing that memory location is now forbidden.
delete [] has destroyed the array created dynamically at address ptr, but has not deleted the pointer itself.
A ptr = nullptr; command would perform that job, by indicating that ptr now points to nothing.
When we learn dynamic allocation in c++, the simplest example about delete[] is :
int main()
{
size_t n = 5;
int *p = new int[n];
delete[] p;
}
In plain English delete[] is able to delete an C-like array from the heap memory which is previously allocated by the new. However, i'm getting errors for the following code.
int main()
{
size_t n = 5;
int *p = new int[n];
p++; //move the pointer to the second element of the array
delete[] p;
}
I was thinking if this could delete the same heap memory, but from the second element onwards. however, i'm getting some error which i dont understand:
Test Prep(51600,0x1000d1dc0) malloc: *** error for object 0x100537134: pointer being freed was not allocated
It's simply undefined behaviour to delete a pointer that's not allocated by new. Undefined behaviour doesn't necessarily give any errors!
You're changing the pointer to point to the next element - which isn't what new returned.
There's no way to partially delete as you wanted. You should look at containers such as std::vector which supports (and manages the allocations) such partial deletion/resizing.
This question already has answers here:
Can I delete[] a pointer that points into an allocated array, but not to the start of it?
(7 answers)
Why can't I delete pointer alone from an array of objects?
(4 answers)
Closed 5 years ago.
Consider, below program which gives runtime error. Point of this question is to understand memory view and management.
#include<iostream>
using namespace std;
int main(void) {
char* arr = new char[10];
char* ptr = NULL;
for(int i = 0; i < 10; i++) {
arr[i] = 'a';
}
cout << arr;
ptr = &arr[5];
delete ptr;
cout << arr;
return 0;
}
new allocates a block of memory. You can free that memory using delete, but you must pass the same address that was returned by new. That's how it works. You can't pass arbitrary addresses to delete.
Another option is to use malloc() and free(). These are older function but then you can also use realloc() to resize the memory. Then, if you want to delete part of the array, you can resize it to be smaller. BUT... you must still copy any data as needed to correctly form the resized array. That is not automatic.
Here is a simple program using dynamic memory.
My question is do I have to delete the memory at the and or the struct will take care of it for me?
#include <iostream>
struct Student {
int grade;
char *name;
};
void print(Student name);
int main() {
Student one;
one.grade = 34;
one.name = new char[12];
int i;
for (i = 0; i < 11; ++i) {
one.name[i] = 'a' + i;
}
one.name[i] = '\0';
print(one);
delete[] one.name;
return 0;
}
void print(Student name) {
std::cout << name.name << " has a score of " << name.grade << "\n";
}
There is a simple rule of thumb- for each call of new you should have one call of delete. In this case you should delete one.name like so : delete [] one.name.
Of course you should do that after you no longer need its value. In this case this is immediately before the return.
Memory allocated dynamically using new or malloc must be freed up when you're done with it using delete or free otherwise you'll get Memory leak.
Make difference between delete and delete[]: the first without subscript operator is used to deleted dynamic memory allocated with new for a pointer. The latter is used for deleting an array allocated dynamically.
So in your case:
one.name = new char[12]; // an array of 12 elements in the heap
delete[] one.name; // freeing up memory
char* c = new char('C'); // a single char in the heap
delete c;
Don't mix new, delete with malloc, free:
This is undefined behavior, as there's no way to reliably prove that memory behind the pointer was allocated correctly (i.e. by new for delete or new[] for delete[]). It's your job to ensure things like that don't happen. It's simple when you use right tools, namely smart pointers. Whenever you say delete, you're doing it wrong.
If you don't want to use unique/shared pointers, you could use a constructor for allocating and a destructor for automatically freeing memory.
If the raw pointer in your structure is an observing pointer, you don't have to delete the memory (of course, someone somewhere in the code must release the memory).
But, if the raw pointer is an owning pointer, you must release it.
In general, every call to new[] must have a matching call to delete[], else you leak memory.
In your code, you invoked new[], so you must invoke delete[] to properly release the memory.
In C++, you can avoid bug-prone leak-prone raw pointers, and use smart pointers or container classes (e.g. std::vector, std::string, etc.) instead.
Creating a Structure does not mean it will handle garbage collection in C++
there is no garbage collection so for every memory you allocate by using new you should use delete keyword to free up space. If you write your code in JAVA you wont have to delete as garbage collector will automatically delete unused references.
Actually the structure won't freeup or delete the memory that you have been created. if in case you want to freeup the space you can do as follows.
#include <iostream>
using namespace std;
int main()
{
char *c = new char[12];
delete[] c;
return(0);
}
This question already has answers here:
What is The Rule of Three?
(8 answers)
Closed 6 years ago.
i couldn't find my answer with googling so im asking here :
Assume that we have code like this and we don't want to overload the copy constructor
#ifndef ARRAY_H
#define ARRAY_H
class Array {
public:
Array(int = 10);
int* ptr;
int size;
}
#endif // ARRAY_H
and we have:
#include <iostream>
#include "Array.h"
using namespace std;
Array::Array(int A)
{
size = (A > 0) ? A : 10;
ptr = new int[size];
for(int i=0; i<size; i++)
{ ptr[i] = i;}
}
and main() is :
Array newArray1(10);
Array newArray2(8);
newArray2 = newArray1;
now our professor said we have dangle problem here because we have same address for both
newArray1 and newArray2
my question is if we delete newArray1 memory : have we memory leak except dangle??? what happened to newArray2's ptr's memory which ptr was pointing to it before getting newArray1 address??? is this part of memory exist now ??? and have we other memory leaks problem ???
To answer your question: You have no destructor delete[]ing the memory you allocate to ptr in the constructor. So yes, you have a leak.
A much better option would be to simply use a std::unique_ptr rather than manual memory management.
Also, why are you not using the constructors initialization list but instead assigning to members in the constructor body?