I have here some line of code. What I am trying to do here is that I would like to allocate 10 objects using overloaded operator new and on the 11th "run out of memory" and throw an exception. I added a static member function that reclaims the memory allocated for the 10th object so that I can use the address back and allocate it to a new object.
I'm still on the learning process for c++ so your critics are highly appreciated.
Help me evaluate my program. I don't know how I can reclaim the memory and then use the address to allocate the next new object.
Thank you.
P.S. how can I use 'this' in overload operator new?
#include <iostream>
#include <cstdlib>
using namespace std;
int count=0;
class RunOutOfMemory : public exception{
public:
const char * Message(){
return "Run out of memory!";
}
};
class ObjectAllocation{
public:
ObjectAllocation(){
cout << count << "Object Allocated at " << &this[count] << endl;
}
//Operator new overloaded
void * operator new(){
count++;
if(count>=11){
throw RunOutOfMemory();
}
}
//Reclaim memory allocated for 10th instance
//so that a new object can be instantiate on its memory address
static void reclaim(){
//delete?
}
};
int main(int argc, char * argv[]){
ObjectAllocation * objAlloc;
int counter=0;
cout << &objAlloc << endl;
while(counter<=20){
counter++;
try{
objAlloc = new ObjectAllocation();
cout << &objAlloc[counter] << endl;
}catch(RunOutOfMemory room){
cout << room.Message() << endl;
objAlloc.reclaim();
}
}
}
Related
This question already has answers here:
C++ new int[0] -- will it allocate memory?
(6 answers)
Closed 4 years ago.
I have a class called MyClass , with a print given when the constructor or distractor is called.
I am trying to allocate memory from new operator. I have some question on the output of below code.
<code>
#include...
class MyClass
{
public:
MyClass()
{
cout << "MyClass Object Created \n";
}
~MyClass()
{
cout << "MyClass Object Deleted\n+";
}
};
int main(int argc, const char * argv[])
{
int size = 0; // if the size is zero
std::cout << "Hello, World!\n";
MyClass *mclass = NULL;
cout << "before allocating the memory :" << mclass << endl;
mclass = new MyClass[size](); //object will not be constructed.
cout << "after allocating the memory :"<< mclass << endl;
delete [] mclass;
cout << "after deallocating the memory :"<< mclass << endl;
return 0;
}
</code>
Questions -
1. if array size is 1, 2,... any int value constructor is called but when the array size is 0 constructor is not called though memory is allocated
according to new operator if the memory is allocated constructor should be called.
With array size zero there are no array items to construct.
It's that simple.
You get a unique address though, and that means at least one byte has been allocated, which must be freed as usual.
I'm worried about this bug. As far as I read its about new/delete errors, but I'm not sure why this just happens.
Well, here is my base class "algoritmo":
class algoritmo{
protected:
int* vector_;
int n_;
public:
algoritmo();
algoritmo(int);
~algoritmo();
void mostrar();
virtual void ordenar(int,int,int)=0;};
And here is one of her childs "qsort":
class quicksort : public algoritmo{
public:
quicksort():algoritmo(){}
quicksort(int j):algoritmo(j){}
~quicksort();
void ordenar(int,int,int);
};
And I do this on main.cpp:
#include <vector>
using namespace std;
int main(void){
vector<algoritmo*> metodos;
int tamvector;
cout << "Size of the vector" << endl;
cin >> tamvector;
metodos.push_back(new quicksort(tamvector));
metodos[0]->mostrar();
metodos[0]->ordenar(0,tamvector,0);
cout << "I did";
metodos[0]->mostrar();
cout << "I didn't access a wrong pos" << endl;
cout << metodos.empty();
return 0;
}
I don't know why, but if I enter size 9,45,20,11,3 it works fine but when I enter size 10 I get numap or double free or corruption.
May someone explain me why?
Thanks for your attention.
Update: information of classes as requested
`**Algoritmo definition**
algoritmo::algoritmo(){
n_=0;
vector_=new int[n_];
}
algoritmo::algoritmo(int tamano){
n_=tamano;
vector_=new int[n_];
srand(time(NULL));
for(int i=0;i<n_;i++){
vector_[i]=rand()%9000+1000;
}
}
algoritmo::~algoritmo(){
delete vector_;
n_=-1;
}
void algoritmo::mostrar(){
for(int i=0;i<n_;i++){
cout << vector_[i] << " ";
}
cout << endl;
}`
And quicksort definition
`quicksort::~quicksort(){}
void quicksort::ordenar(int ini,int fin,int relleno1){
int i,f,p,x;
i=ini;
f=fin;
p=vector_[(i+f)/2];
while(i < f){
while(vector_[i]<p)
i++;
while(vector_[f]>p)
f--;
if(i<=f){
x=vector_[i];
vector_[i]=vector_[f];
vector_[f]=x;
i++;
f--;
}
}
if(ini <f)
ordenar(ini,f,relleno1);
if(i < fin)
ordenar(i,fin,relleno1);
}`
Your class manages a dynamically allocated array, but does not follow the rule of three in that you have not provided a copy constructor or assignment operator that takes care of making copies of the managed resources where applicable. So when you copy or assign, you get more than one instance pointing to the same dynamically allocated array. They all attempt to call delete on it at the end of their lifetime, giving you the double-free error.
You can fix this easily by using an std::vector<int> as data member instead of using a raw pointer to a dynamically allocated array.
Note: there may be other errors, but this particular one is a source of undefined behaviour and should be fixed.
I'm very new to C++ and I wish to make clear some points regarding memory management using the operator "new ..." and the operator "delete ...".
I will post some code of mine, and I ask if you please would correct my comments if they are wrong.
I'm also dealing with virtual functions and interface, which is clear by reading the code, and I also ask you if i'm approaching them the right way.
Then I have a more direct question, when should I use "new[] ..." or "delete[] ...", and how should I use them correctly?
PS: the output of code below is:
car built
motorcycle built
car has 4 wheels
motorcycle has 2 wheels
car destroyed
motorcycle destroyed
That's the main.cpp source:
#include <iostream>
using namespace std;
class vehicle
{
public:
virtual
~vehicle()
{
}
virtual void
wheelNum() = 0;
};
class car : public vehicle
{
public:
car()
{
cout << "car built" << endl;
}
~car()
{
cout << "car destroyed" << endl;
}
void
wheelNum()
{
cout << "car has 4 wheels" << endl;
}
};
class motorcycle : public vehicle
{
public:
motorcycle()
{
cout << "motorcycle built" << endl;
}
~motorcycle()
{
cout << "motorcycle destroyed" << endl;
}
void
wheelNum()
{
cout << "motorcycle has 2 wheels" << endl;
}
};
int
main()
{
// motorVehicle[2] is allocated in the STACK and has room for 2 pointers to vehicle class object
// when I call "new ...", I allocate room for an object of vehicle class in the HEAP and I obtain its pointer, which is stored in the STACK
vehicle* motorVehicle[2] = { new (car), new (motorcycle) };
for (int i = 0; i < 2; i++)
{
// for every pointer to a vehicle in the array, I access the method wheelNum() of the pointed object
motorVehicle[i] -> wheelNum();
}
for (int i = 0; i < 2; i++)
{
// given that I allocated vehicles in the HEAP, I have to eliminate them before terminating the program
// nevertheless pointers "motorVehicle[i]" are allocated in the STACK and therefore I don't need to delete them
delete (motorVehicle[i]);
}
return 0;
}
Thanks you all.
Memory allocated with new is on the HEAP, everything else in on the stack. So in your code, you have
vehicle* motorVehicle[2] = { new (car), new (motorcycle) };
On the stack there is an array of two pointers vehicle*[2], and on the heap are two objects, a car and a motocycle.
Then you have two loops
for (int i = 0; i < 2; i++)
each of which create an integer on the stack for the duration of the loop.
Concerning your code: the array of pointers is a local variable,
which would be allocated on the stack. What the pointers them
selves point to is, in the case of your example, allocated
dynamically (on the heap).
Concerning the "more direct question": I've yet to find any case
where new[] should be used. It's present for reasons of
completeness, but it doesn't really have any reasonable use.
I have an assignment that requires me to create a "Heap" class that allocates and deallocates memory. I believe that my code works and the solution builds and runs properly but I want to make sure that I am not getting any memory leaks. I also need to add some code that checks if the desired amount to be allocated to the heap is even available...if someone were to allocate a very large amount. How is it possible to check if the memory allocated on the heap is available or NULL if there is not enough memory. Here is my code so far:
#include <iostream>
using namespace std;
class Heap{
public:
double* allocateMemory(int memorySize)
{
return new double[memorySize];
};
void deallocateMemory(double* dMemorySize)
{
delete[] dMemorySize;
};
};
int main()
{
Heap heap;
cout << "Enter the number of double elements that you want to allocate: " << endl;
int hMemory;
const int doubleByteSize = 8;
cin >> hMemory;
double *chunkNew = heap.allocateMemory(hMemory);
cout << "The amount of space you took up on the heap is: " <<
hMemory*doubleByteSize << " bytes" <<
starting at address: " << "\n" << &hMemory << endl;
heap.deallocateMemory(chunkNew);
system("pause");
return 0;
}
It's not necessary to check beforehand, just try to allocate memory and if you can't, then catch the exception. In this case it is of type bad_alloc.
#include <iostream>
#include <new> // included for std::bad_alloc
/**
* Allocates memory of size memorySize and returns pointer to it, or NULL if not enough memory.
*/
double* allocateMemory(int memorySize)
{
double* tReturn = NULL;
try
{
tReturn = new double[memorySize];
}
catch (bad_alloc& badAlloc)
{
cerr << "bad_alloc caught, not enough memory: " << badAlloc.what() << endl;
}
return tReturn;
};
Important note
Be sure to guard against double-freeing memory. One way to do that would be to pass your pointer to deallocateMemory by reference, allowing the function to change the pointer value to NULL, thereby preventing the possibility of delete-ing the pointer twice.
void deallocateMemory(double* &dMemorySize)
{
delete[] dMemorySize;
dMemorySize = NULL; // Make sure memory doesn't point to anything.
};
This prevents problems like the following:
double *chunkNew = heap.allocateMemory(hMemory);
heap.deallocateMemory(chunkNew);
heap.deallocateMemory(chunkNew); // chunkNew has been freed twice!
I am trying to get a grasp on pointers and their awesomeness as well as a better C++ understanding. I don't know why this wont compile. Please tell me what is wrong? I'm trying to initialize the pointer when an instance of the class is created. If I try with a normal int it works fine but when I tried to set it up with a pointer i get this in the console
Running…
Constructor called
Program received signal: “EXC_BAD_ACCESS”.
sharedlibrary apply-load-rules all
Any assistance is appreciated greatly.
Here is the code
#include <iostream>
using namespace std;
class Agents
{
public:
Agents();
~Agents();
int getTenure();
void setTenure(int tenure);
private:
int * itsTenure;
};
Agents::Agents()
{
cout << "Constructor called \n";
*itsTenure = 0;
}
Agents::~Agents()
{
cout << "Destructor called \n";
}
int Agents::getTenure()
{
return *itsTenure;
}
void Agents::setTenure(int tenure)
{
*itsTenure = tenure;
}
int main()
{
Agents wilson;
cout << "This employees been here " << wilson.getTenure() << " years.\n";
wilson.setTenure(5);
cout << "My mistake they have been here " << wilson.getTenure() <<
" years. Yep the class worked with pointers.\n";
return 0;
}
You don't ever create the int that the pointer points to, so the pointer is pointer to an area of memory that doesn't exist (or is used for something else).
You can use new to get a block of memory from the heap, new returns the address of the memory location.
itsTenure = new int;
So now itsTenure holds the memory location you can dereference it to set its value.
The changed constructor is as follows:
Agents::Agents()
{
cout << "Constructor called \n";
itsTenure = new int;
*itsTenure = 0;
}
But you must also remember to delete it using delete
Agents::~Agents()
{
cout << "Destructor called \n";
delete itsTenure;
}
You are just missing a new, in the constructor.
itsTenure = new int;
You don't need to make this a pointer, however. Why are you?
You have to allocate a block of memory for your int, and only then use the address of this block of memory (the pointer). This is done with new :
cout << "Destructor called \n";
itsTenure = new int;
*itsTenure = 0;
Then you have to release the memory in the destructor with delete:
cout << "Destructor called \n";
delete itsTenur;
*itsTenure = 0 does not initialize the pointer. It writes 0 to the location that itsTenure points to. Since you never specified where itsTenure points to, that might be anywhere and the behaviour is undefined (an access violation like you're getting being the most likely result).
You need to allocate memory for *tenure in the constructor:
Agents::Agents()
{
cout << "Constructor called \n";
itsTenure = new int;
*itsTenure = 0;
}