I am trying to implement my own class Alloc which will help in the dynamic allocation of objects..
I want to keep track of the number of allocated objects in my program. So, each time a new instance of an object is allocated, the counter increments by one and decrements when an object is destroyed. When my program shuts down, if the counter is not at zero, the object prints an error message to the screen and has the program hang until the user hits enter..
This is what I have so far.. I hope you guys can help me to implement this..
class Alloc{
static int counter;
public:
Alloc(){ counter++; };
Alloc(int *d, static int size, const Alloc& c){
d=(int *) malloc(size*sizeof(int));;
//d=new int[size];
Alloc *my_alloc;
//my_alloc = new Alloc[size]; //note that the type is a Myclass pointer
for(int i=0; i<size; i++){
my_alloc[i] = new Alloc[size];
}
//for(int i=0; i < size; i++){
// d[i]=c.d[i];
//}
}
~Alloc(){ counter--; }
};
I know a lot is missing so, I will appreciate help and fixing mistakes too..
Thanks!!!
d=(int *) malloc(size*sizeof(int));;
d=new int[size];
The second line here is overwriting the d pointer with a second allocation, so the memory allocated by malloc is being lost!
If you really want to do it this way you need to use placement new, i.e. something like
d=(int *) malloc(size*sizeof(int));;
e=new (d) int[size];
though the details are quite tricky to get right.
To just count the number of objects in your programme though, there is a much easier option. Implement a templated "mixin" which contains a static counter for each type. Something like
template <typename T>
struct countable
{
countable() { _count++; }
countable(const countable&) { _count++; }
~countable() { _count--; }
static int get_count() { return _count; }
private:
static int _count;
};
and then having your objects inherit from this, as in
class MyClass : countable<MyClass>
{
// whatever
};
It's simple, and easy to turn into a no-op for release builds.
the track of number of instances of class say Alloc can also be kept as
class Alloc
{
Public:
static int Coounter; // object counter
// Constructor
Alloc(){
Counter++;}
// Destructor
~Alloc()
{
Counter--;
}
};
Simple, easy to use and maintainable
Related
I'm having a little trouble grasping some concepts with C++ arrays.
On my assignment, I did something like the code below. From what I can tell, this not only creates space on the heap for [size] Object1 objects, but also initializes all of them too. Can somebody explain what is exactly happening on the heap and stack here?
class Object1
{
Private:
int dummy;
Public:
Object1();
};
Object1::Object1()
{
dummy = 1;
}
class Foo
{
private:
Object1 * myObject;
public:
Foo(int size);
};
Foo::Foo(int size)
{
myObject = new Object1[size];
}
If Object1's constructor had taken a parameter, like in the code below, then what would happen differently on the stack and heap, if anything? I'm not sending any parameters into each instance of object1, so would it still initialize any object, or just create the space?
class Object1
{
Private:
int dummy;
Public:
Object1(int myInt);
};
Object1::Object1(int myInt)
{
dummy = myInt;
}
I also saw the code below somewhere. What is happening in this case, and how is it different than the cases above?
myclass *array[10];
for (int i = 0 ; i != 10 ; i++) {
array[i] = new myclass();
}
I've completed the assignment, but am just trying to make sure I understand what's happening behind the scenes.
Thank you in advance for taking the time to help!
If your class does not have a default constructor, you won't be able to use:
myObject = new Object1[size];
The difference between
myObject = new Object1[size];
and
myclass *array[10];
for (int i = 0 ; i != 10 ; i++) {
array[i] = new myclass();
}
The first one allocates size objects and stores the pointer to the array of objects in myObject.
The second one allocates 10 objects but there are 10 pointers. Each pointer points to only one dynamically allocated object.
I currently have a c++ class as follows:
template<class T>
class MyQueue {
T** m_pBuffer;
unsigned int m_uSize;
unsigned int m_uPendingCount;
unsigned int m_uAvailableIdx;
unsigned int m_uPendingndex;
public:
MyQueue(): m_pBuffer(NULL), m_uSize(0), m_uPendingCount(0), m_uAvailableIdx(0),
m_uPendingndex(0)
{
}
~MyQueue()
{
delete[] m_pBuffer;
}
bool Initialize(T *pItems, unsigned int uSize)
{
m_uSize = uSize;
m_uPendingCount = 0;
m_uAvailableIdx = 0;
m_uPendingndex = 0;
m_pBuffer = new T *[m_uSize];
for (unsigned int i = 0; i < m_uSize; i++)
{
m_pBuffer[i] = &pItems[i];
}
return true;
}
};
So, I have this pointer to arrays m_pBuffer object and I was wondering if it is possible to replace this way of doing things with the c++ smart pointer perhaps? I know I can do things like:
std::unique_ptr<T> buffer(new T[size]);
Is using a vector of smart pointers the way to go? Is this recommended and safe?
[EDIT]
Based on the answers and the comments, I have tried to make a thread-safe buffer array. Here it is. Please comment.
#ifndef __BUFFER_ARRAY_H__
#define __BUFFER_ARRAY_H__
#include <memory>
#include <vector>
#include <mutex>
#include <thread>
#include "macros.h"
template<class T>
class BufferArray
{
public:
class BufferArray()
:num_pending_items(0), pending_index(0), available_index(0)
{}
// This method is not thread-safe.
// Add an item to our buffer list
void add(T * buffer)
{
buffer_array.push_back(std::unique_ptr<T>(buffer));
}
// Returns a naked pointer to an available buffer. Should not be
// deleted by the caller.
T * get_available()
{
std::lock_guard<std::mutex> lock(buffer_array_mutex);
if (num_pending_items == buffer_array.size()) {
return NULL;
}
T * buffer = buffer_array[available_index].get();
// Update the indexes.
available_index = (available_index + 1) % buffer_array.size();
num_pending_items += 1;
return buffer;
}
T * get_pending()
{
std::lock_guard<std::mutex> lock(buffer_array_mutex);
if (num_pending_items == 0) {
return NULL;
}
T * buffer = buffer_array[pending_index].get();
pending_index = (pending_index + 1) % buffer_array.size();
num_pending_items -= 1;
}
private:
std::vector<std::unique_ptr<T> > buffer_array;
std::mutex buffer_array_mutex;
unsigned int num_pending_items;
unsigned int pending_index;
unsigned int available_index;
// No copy semantics
BufferArray(const BufferArray &) = delete;
void operator=(const BufferArray &) = delete;
};
#endif
Vector of smart pointers is good idea. It is safe enough inside your class - automatic memory deallocation is provided.
It is not thread-safe though, and it's not safe in regard of handling external memory given to you by simple pointers.
Note that you current implementation does not delete pItems memory in destructor, so if after refactoring you mimic this class, you should not use vector of smart pointers as they will delete memory referenced by their pointers.
On the other side you cannot garantee that noone outside will not deallocate memory for pItems supplied to your Initialize. IF you want to use vector of smart pointers, you should formulate contract for this function that clearly states that your class claims this memory etc. - and then you should rework outside code that calls your class to fit into new contract.
If you don't want to change memory handling, vector of simple pointers is the way to go. Nevertheless, this piece of code is so simple, that there is no real benefit of vector.
Note that overhead here is creation of smart pointer class for each buffer and creation of vector class. Reallocation of vector can take up more memory and happens without your direct control.
The code has two issues:
1) Violation of the rule of zero/three/five:
To fix that you do not need a smart pointer here. To represent a dynamic array with variable size use a std:vector<T*>. That allows you to drop m_pBuffer, m_uSize and the destructor, too.
2) Taking the addresses of elements of a possible local array
In Initialize you take the addresses of the elements of the array pItems passed as argument to the function. Hence the queue does not take ownership of the elements. It seems the queue is a utility class, which should not be copyable at all:
template<class T>
class MyQueue
{
std::vector<T*> m_buffer;
unsigned int m_uPendingCount;
unsigned int m_uAvailableIdx;
unsigned int m_uPendingndex;
public:
MyQueue(T *pItems, unsigned int uSize)
: m_buffer(uSize, nullptr), m_uPendingCount(0), m_uAvailableIdx(0), m_uPendingndex(0)
{
for (unsigned int i = 0; i < uSize; i++)
{
m_buffer[i] = &pItems[i];
}
}
private:
MyQueue(const MyQueue&); // no copy (C++11 use: = delete)
MyQueue& operator = (const MyQueue&); // no copy (C++11 use: = delete)
};
Note:
The red herring is the local array.
You may consider a smart pointer for that, but that is another question.
I'm trying to assign a node to a pointer along an array of pointers but it keeps telling me that my array was not declared in the scope. I'm totally confused on how or why so any help would be greatly beneficial! Thanks for taking the time to respond!
#include <iostream>
#include "book.h"
using namespace std;
class bookstore
{
private:
int amount = 5;
int counting = 0;
public:
bookstore()
{
bookstore *store;
store = new book*[amount];
for(int i = 0; i < amount; i++)
{
store[i] = NULL;
}
}
~bookstore(){ delete[] store; }
void addbook(string a,string b, string c, string d, string e)
{
if (counting == amount)
{
cout<<"Full House!"<<endl;
return;
}
store[counting] = new book(a,b,c,d,e);
counting++;
}
void print()
{
for(int i = 0; i < amount; i++)
{
cout<<store[i]->name<<" "<<store[i]->publisher<<" "<<store[i]->year<<" "<<store[i]->price<<" "<<store[i]->category<<endl;
}
}
};
Your pointer store is local to the default constructor. It looks like you're after a data member. Furthermore, you seem to be after an array of pointers. If so, you need bookstore needs to be a pointer to pointer:
class bookstore
{
private:
bookstore** store; // or bookstore* store
int amount = 5;
int counting = 0;
and fix the constructor to use that:
bookstore()
{
store = new book*[amount]; // or store = new book[amount]
....
Note that your class is attempting to manage dynamically allocated resources, so you will need to take care of the copy constructor and assignment operators (either make the class non-copyable and non-assignable, or implement them. The defaults are not acceptable. See the rule of three.) If you are really using an array of dynamically allocated pointers, then you need to fix your destructor too. Currently, it only deletes the array, but not the objects pointed at by the pointers in it.
The better solution would be to use a class that manages the resources for you and has the desired semantics. It is easier to have each class handle a single responsibility.
I have a class called Foo which has a member that is a pointer to a vector of pointers to another class called Bar. I initialise it in the constructor but I'm not sure how to deallocate it in the destructor. I'm still learning. Would appreciate your help. The reason for having this member is so that the scope persists beyond that method i.e. beyond the stack. Thanks.
#include <iostream>
#include <vector>
using namespace std;
class Bar {};
class Foo {
public:
Foo() {
bars = new vector<Bar*>*[10];
for (int i = 0; i < 10; i++) {
bars[i]->push_back(new Bar());
}
}
~Foo () {
for (int i = 0; i < 10; i++) {
// TODO: how to clean up bars properly?
}
}
private:
vector<Bar*>** bars;
};
int main () {
new Foo();
return 0;
}
Update: I appreciate the feedback on all fronts. I'm new to C and C++. Basically I wanted a 2d structure as a class member that would persist for the lifetime of the class. The reason the outer structure is an array is because I know how big it needs to be. Otherwise I was previously using vector of vectors.
This isn't even allocated properly. You allocate an array of pointers to std::vector<Bar*>, but never any std::Vector<Bar*>.
The best thing to do is just something like std::vector<std::unique_ptr<Bar>> or even std::unique_ptr<std::vector<std::unique_ptr<Bar>>> or something like that. What you've got is just WTF.
Or std::unique_ptr<std::array<std::unique_ptr<std::vector<std::unique_ptr<Bar>>>, 10>>.This is an exact match (but self-cleaning).
The number of pointers is a bit ridiculous, as all they are doing is causing confusion and leaks, as evident from non-proper initialization and the question's title. You don't actually need any pointers at all, and don't have to worry about any cleanup.
For a 2D array with the first dimension passed into the constructor, you can use a vector of vectors:
std::vector<std::vector<Bar>> bars;
To initialize the outer vector with the passed in size, use an initializer:
Foo(size_t size)
: bars(size) {}
When the object is destroyed, bars and all of it elements are as well, so there's no chance of forgetting to clean up or doing so improperly.
If performance is an issue, this can be translated into a sort of Matrix2D class that acts like a 2D array, but really only has an underlying 1D array.
EDIT: In the case of a 2D structure (and you said you know how big your 2D structure needs to be, so we'll assume that the 10 in your loops is the size of the 2D array you desire.
#include <iostream>
#include <vector>
using namespace std;
class Bar {
public:
int BarInfo;
};
class Foo {
public:
Foo() {
// Allocates 10 vector spots for 10 bar elements - 100 bars, 10 x 10
for (int i = 0; i < 10; i++) {
// Puts 10 bars pointer at the end;
// Heap-allocated (dynamically), which
// means it survives until you delete it
// The [10] is array syntax, meaning you'll have 10 bars
// for each bars[index] and then
// you can access it by bars[index][0-9]
// If you need it to be more dynamic
// then you should try vector<vector<Bar>>
bars.push_back(new Bar[10]);
}
}
Bar* operator[] (int index) {
return bars[index];
}
~Foo () {
// Cleanup, because you have pointers inside the vector,
// Must be done one at a time for each element
for (int i = 0; i < bars.size(); i++) {
// TODO: how to clean up bars properly?
// Each spot in the vector<> contains 10 bars,
// so you use the array deletion
// and not just regular 'delete'
delete[] bars[i]; // deletes the 10 array elements
}
}
private:
// vector might not be a bad idea.
vector<Bar*> bars;
};
This is the main I have for testing the code written, and it works like you would think a 2D array should work:
int main ( int argc, char* argv[] ) {
Foo foo;
// Bar at 1st row, 2nd column ( row index 0, column index 1 )
// Bar& is a reference
Bar& bar12 = foo[0][1];
bar12.BarInfo = 25;
int stuffInsideBar = foo[0][1].BarInfo; // 25
return 0;
}
I hope that helps and gets you closer to what you're doing. I've used a technique here that might go over a starters head to make the Foo class behave like you would think a 2D array would. It's called operator overloading. It's a powerful feature in C++, so once you master more basics it might be useful to you in your future projects or current one. Good luck!
~~~~~~~~~~~~~~~~~~~~~~~
OLD ANSWER BEFORE EDIT
~~~~~~~~~~~~~~~~~~~~~~~
It appears you're doing far too much indirection. While another person's answer shows you how to clean up what you've managed to do, I think you could benefit from changing how exactly you're handling the class.
#include <iostream>
#include <vector>
using namespace std;
class Bar {};
class Foo {
public:
Foo() : bars() {
// bars is no longer a pointer-to-vectors, so you can just
// allocate it in the constructor - see bars() after Foo()
//bars = new vector<Bar>();
for (int i = 0; i < 10; i++) {
// Puts 1 bar pointer at the end;
// Heap-allocated (dynamically), which
// means it survives until you delete it
bars.push_back(new Bar());
}
}
~Foo () {
// Cleanup, because you have pointers inside the vector,
// Must be done one at a time for each element
for (int i = 0; i < 10; i++) {
// TODO: how to clean up bars properly?
// TODOING: One at a time
delete bars[i]; // deletes pointer at i
}
}
private:
// You don't need to ** the vector<>,
// because it's inside the class and
// will survive for as long as the class does
// This vector will also be copied to copies of Foo,
// but the pointers will remain the same at the time
// of copying.
// Keep in mind, if you want to share the vector, than
// making it a std::shared_ptr of a
// vector might not be a bad idea.
vector<Bar*> bars;
};
If you pass the class by reference into functions, than the vector<Bar*> inside the class won't copy itself or delete itself, making it persist past a single stack frame.
In your main, this should clean up properly and is a lot easier to keep track of than vector** . However, if for some reason vector** is required, than home_monkey's answer should help you more.
I think there is an issue with allocation. The line
new vector <Bar*> * [10]
will give you an array of points to objects of type vector <Bar*> * and you
will need to allocate some additional memory for your vector <Bar*> type.
I've had a go,
Foo()
{
bars = new vector<Bar*>*[10]; // A.
for (int i = 0; i < 10; i++)
{
bars[i] = new vector<Bar*>; // B. Extra memory assigned here.
bars[i]->push_back(new Bar); // C.
}
}
To free resources, you'll have to reverse the above
~Foo ()
{
for (int i = 0; i < 10; i++)
{
// I'm assuming that each vector has one element
delete bars[i][0]; // Free C
delete bars[i]; // Free B
}
delete [] bars; // Free A
}
I don't believe you're even allocating it properly. To undo what you've done so far, all you'd have to do is:
for(int i=0; i < 10; ++i)
while(bars[i]->size > 0)
{
delete *bars[i]->front();
pop_front();
}
delete[] bars;
But, you need to allocate each of the vectors themselves, for instance in the constructor:
for(int i=0; i<10; ++i)
bars[i] = new vector<Bar*>();
Which would require you change the destructor to:
for(int i=0; i < 10; ++i)
{
while(bars[i]->size > 0)
{
delete *bars[i]->front();
pop_front();
}
delete bars[i];
}
delete[] bars;
With regard to your update, I would then suggest changing the type of bars to:
vector<Bar*>* bars;
and the allocation to (without the need to do the for loop allocation suggested above):
bars = new vector<Bar*>[10];
I should probably be sleeping. Instead, I'm coding. Specifically, I've written The World's Worse Memory Allocator(TM). It's got an array of bytes (chars) to use for memory for stuff; it's got a list of used memory blocks; it's got an index to allocate memory from. It even allocates memory. Deallocates, not so much.
That shouldn't be a problem, though, as to the best of my knowledge, nothing is new'd outside of the array and list classes and the destructor for those is called the proper number of times.
Edit: The problem is, the program enters what appears to be an infinite loop somewhere in the c++ back-end code itself, shortly after the MemoryManager's destructor is called. In fact, if the MemoryManager is put inside the Try-Catch block, the program never makes it outside the Try-Catch block. I need to know why and how to fix it, please, thanks.
This is the main loop which is doing terribly important allocations:
int _tmain(int argc, _TCHAR* argv[])
{
MemoryManager memoryManager = MemoryManager(1024);
try
{
int * n;
for (int t = 0; t < 32; ++t)
{
n = (int*)memoryManager.Allocate(4);
}
} catch (char* str) { std::cout << str; }
return 0;
}
And the MemoryManager, in all it's newbie glory:
// A memory manager
#pragma once
#include "stdafx.h"
#include "Array.h"
#include "SmartPointer.h"
class MemBlock
{
public:
unsigned int Start;
unsigned int End;
MemBlock() { Start = 0; End = 0; }
MemBlock(unsigned int start, unsigned int end)
{
Start = start; End = end;
}
~MemBlock() { }
};
class MemoryManager
{
private:
Array<char> memory;
List<MemBlock> memBlocks;
int index;
public:
MemoryManager(unsigned int size)
{
memory = Array<char>(size);
memBlocks = List<MemBlock>(size / 24);
index = 0;
}
~MemoryManager() { }
void* Allocate(unsigned int size)
{
memBlocks.Add(&MemBlock(index, index + size));
void* r = (void*)(memory.insecureAccess + index);
index += size;
return r;
}
};
Thanks.
You don't seem to have asked a question here, but I'm going to point out a horrible flaw in your approach anyway :)
If you are planning to write a Deallocate(void*) method then you are going to struggle.
You can match the void* pointer against your memBlocks list to determine which MemBlock it is, but you will only be able to reduce index if that MemBlock happens to be the last one returned by Allocate otherwise it is just a free hole in your array.
For a basic solution to this you would need a list of the free blocks and you would take allocated blocks from that list, and add them back to the list when they were deallocated.
This approach is called a free list: http://en.wikipedia.org/wiki/Free_list
Solved - Error in ignorance; it was an indirect error. I was using "delete theArray;" in the Array destructor (Array also being the base class of List) when I should have been using "delete [] theArray". The pause is now gone and the problem seems solved. Thanks for your time.