so this is my code [ notice that I commented the cstr and destructor]
#include <iostream>
#include <stdlib.h>
#include <array>
class MyIntClass
{
int _mymember;
public:
// MyIntClass(){}
// ~MyIntClass(){}
void *operator new(size_t size)
{
std::cout << "new: Allocating " << size << " bytes of memory" << std::endl;
void *p = malloc(size);
return p;
}
void operator delete(void *p)
{
std::cout << "delete: Memory is freed again " << std::endl;
free(p);
}
void *operator new[](size_t size)
{
std::cout << "new: Allocating " << size << " bytes of memory" << std::endl;
void *p = malloc(size);
return p;
}
void operator delete[](void *p)
{
std::cout << "delete: Memory is freed again " << std::endl;
free(p);
}
};
void line(){
std::cout << "\n--------------------------------------------------\n" << std::endl;
}
int main()
{
line();
std::cout << "Using new overloading and malloc\nWe will create one object of MyIntClass that is supposed to be 4 bytes" << std::endl;
MyIntClass *m1 = new MyIntClass();
line();
//I want to create an array of the MyIntClass of two objects
std::cout << "Now we create array of MyIntClass using <array> header" << std::endl;
std::array<MyIntClass, 2> z = {};
std::cout << " The elements in the array z = "<< z.size() <<std::endl;
std::cout << "The memory allocated for array z = " << sizeof(z) << std::endl;
line();
std::cout << "\nNow we create array using new[] overloading and malloc " << std::endl;
MyIntClass *i = new MyIntClass[2]();
delete[] i;
}
now the result is as follow:
Using new overloading and malloc
We will create one object of MyIntClass that is supposed to be 4 bytes
new: Allocating 4 bytes of
memory
Now we create array of MyIntClass using <array> header
The elements in the array z = 2
The memory allocated for array z = 8
Now we create array using new[] overloading and malloc
new: Allocating 8 bytes of memory
To me as inexperienced C++ programmer I think every thing is working as expected
Now If I uncomment the constructor the same result will happen
however when I uncomment the destructor different result will occur
Now we create array using new[] overloading and malloc
new: Allocating 12 bytes of memory
So my question is what is the explanation for this:
creating array of two objects each is 4 bytes will result in 8byte memory allocation for the array in both methods using the array library or the overloading the new[] and malloc.
however when we have a destructor for the object the malloc will allocate 12 bytes not 8 bytes for this array of 2 elements.
I saw this question on SO but it didn't explain my case
following is my compiler version :
gcc version 8.2.0 (MinGW.org GCC-8.2.0-3)
The reason for extra allocated memory is that the compiler needs to know the number of elements in the array in order to be able to call destructors on each element of the array when you call delete[]. For trivially destructible types the compiler doesn't need to call destructor, so the extra space for the array size is not needed.
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 am learning how vectors work in c++, and wrote a sample program to try to learn how memory with vectors are handled.
#include <iostream>
#include <vector>
int main()
{
//Test 1:
double n = 3.5;
std::vector<double> test;
std::cout << sizeof(test) << std::endl;
test.push_back(n);
std::cout << sizeof(test) << std::endl;
std::cout << std::endl;
std::cout << std::endl;
std::cout << std::endl;
//Test 2
std::vector<int> test2;
std::cout << sizeof(test2) << std::endl;
for (int i = 0; i < 1000; i++) {
test2.push_back(i);
}
std::cout << sizeof(test2) << std::endl;
}
Interestingly, the program prints out 24 as the number of bytes stored each-time. Despite adding new elements to the vector. How is the amount of memory that the vector occupies when it is initially declared the same as after I have added elements to the vector?
Internally, the vector object has a pointer to dynamically-allocated memory that contains the elements. When you use sizeof(test) you're just getting the size of the structure that contains the pointer, the size of the memory that it points to is not included.
This memory has to be dynamically-allocated so that the vector can grow and shrink as needed. It's not possible for a class object to change its size.
To get the amount of memory being used by the data storage, use sizeof(double) * test.capacity().
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();
}
}
}
I want to overload the operator new[] to get the number of how many objects are to be created.
the best possible solution is to overload new[] in a way that the when creating an object using new[] would not necessitate the caller to write any extra code.
i.e using simply:
Myclass objectsArray = new Myclass[5];
example overload:
class Myclass
{
...
public:
void* operator new[](size_t size)
{
int numberOfObjects = figure out how to get number of objects to be created by this call to new[]
std::cout << "requesting: " << numberOfObjects << " objects" << std::endl;
void * temp = malloc(size) ;
return temp ;
}
...
}
the following example program:
Myclass objectsArray = new Myclass[4];
would output:
requesting: 4 objects
edit:
I want to do this just in MyClass not globaly
edit:
I'm on ‎Lubuntu 12.0 with GCC version 4.8.1
edit: Purpose of the question:
I'm using a custom memory pool allocator that can't allocate arrays out of the box. so I need to know how many objects are requested and create them one by one using a loop with the pool allocator.
You need to define a class-specific operator new. This works for me, but beware of alignment, derived classes sizes, and allocation overhead issues in the count/sizeof(MyClass) expression:
#include <iostream>
#include <memory>
#include <new>
struct MyClass {
int dummy[8];
void *operator new[](std::size_t count) {
std::cout << "allocating " << count << " bytes, " << ((count-sizeof(void*))/sizeof(MyClass)) << " items\n";
return ::operator new[](count);
}
};
int main() {
auto x = std::make_unique<MyClass[]>(10);
}
(prints: allocating 10 items) I think one can determine the exact overhead for your compiler/stdlib combination empirically by doing something like:
#include <iostream>
#include <memory>
#include <new>
struct MyClass {
char c;
char d;
virtual ~MyClass() {} // needed for introducing overhead
void *operator new[](std::size_t count) {
void *p = ::operator new[](count);
std::cout << "allocating " << count << " bytes\n";
return p;
}
};
int main() {
for( auto count : { 1, 5, 10, 20 } ) {
std::cout << "allocating " << sizeof(MyClass) << " * " << count << " items\n";
auto x = new MyClass[count];
delete[] x;
}
}
This will print, in my machine (and on Coliru):
allocating 16 * 1 items
allocating 24 bytes, 1 items
allocating 16 * 5 items
allocating 88 bytes, 5 items
allocating 16 * 10 items
allocating 168 bytes, 10 items
allocating 16 * 20 items
allocating 328 bytes, 20 items
So, our count/sizeof(MyClass) (here) should be something like
(count-sizeof(void*))/sizeof(MyClass)
But YMMV, etc.
LAST EDIT (I hope)
I had success on 64-bits linux (clang-3.4, clang-3.5 & gcc-4.8, libstdc++ & libc++) with the following how_many_elements function:
template<class T>
std::size_t how_many_elements(std::size_t bytes) {
return (bytes -
((!std::is_trivially_destructible<T>::value)*sizeof(void*))
) / sizeof(T);
}
So your operator new becomes something like:
void *operator new[](std::size_t count) {
std::cout << "allocating " << count << " bytes, " << how_many_elements<MyClass>(count) << " items\n";
return ::operator new[](count);
}
But I have not tested it in 32-bits environments and the YMMV still applies. And remember to replicate the operator new for every derived class of MyClass, obviously replacing MyClass for MyDerivedClass or whatever...
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!