I need to find out what objects are not deleted between application states, here is code example:
#include <vector>
#include <map>
class MyClass {
public:
int myNum;
};
std::vector<MyClass *> firstStateClasses;
std::map<int, MyClass *> stateClasses;
void MakeFirstState()
{
for (int i = 0; i < 10; ++i)
{
MyClass* firstClass = new MyClass();
firstStateClasses.push_back(firstClass);
}
}
void DeleteFirstState()
{
for (auto p : firstStateClasses)
{
delete p;
}
firstStateClasses.clear();
}
void MakeState(int state)
{
MyClass* randomClass = new MyClass();
stateClasses.insert(std::make_pair(state, randomClass));
}
void DeleteState(int state)
{
auto itr = stateClasses.find(state);
if (itr != stateClasses.end())
{
delete itr->second;
stateClasses.erase(itr);
}
}
int main()
{
MakeFirstState();
MakeState(0);
//Leak is here, state wasnt deleted.
MakeState(1);
//I need to know here objects that were made only in MakeState(0) and not deleted.
DeleteState(1);
MakeState(2);
DeleteState(2);
DeleteFirstState();
}
I was trying to use Visual Studio memory heap profiling, but it isnt very usefull since i cant single out only objects that were made in MakeState(0) and were not deleted after MakeState(1).
Related
I am trying to initiate an object with an array. Is there a way to do it with pointers or should i find another way to do this.
EDIT: I want to write this code with dynamic memory allocation, I know vector is better way to solve this.
#include <iostream>
template <class t>
class die {
private:
int sideCount;
t* valueOfSides;
public:
die(int side, t arr[]) {
sideCount = side;
valueOfSides = (t*)malloc(side * sizeof(t));
for (int counter; counter < side; counter++) {
valueOfSides[counter] = val[counter];
}
}
~die() {
free(valueOfSides);
}
};
int main() {
die<int> sixsided(6, {1,2,3,4,5,6});
}
The right ways to do this would be
std::vector<t> valueOfSides;
template<size_t len> die(t (&arr)[len])
: valueOfSides(std::begin(arr), std::end(arr))
{}
or
std::vector<t> valueOfSides;
die(std::initializer_list<t> arr) : valueOfSides(arr) {}
I think. Though really, the best answer is
std::vector<t> valueOfSides;
die(std::vector<t> arr) : valueOfSides(std::move(arr)) {}
One should never use raw pointers to own memory in C++, and virtually never use new or malloc. As it is, you have undefined behavior in your code because of misusing malloc.
If you're absolutely insane, or doing homework, it can be done with raw pointers, though I doubt I can get it entirely right without tests and a compiler.
template<class t>
class die {
private:
int sideCount;
t* valueOfSides;
public:
die(int side, t* arr) {
sideCount = 0;
std::size_t buffer_size = sizeof(t)*side;
char* buffer;
try {
buffer = new char[side];
valueOfSides = reinterpret_cast<t*>(buffer);
for(int i=0; i<side; i++) {
new(valueOfSides+i)t(arr[i]);
sideCount++;
}
} catch(...) {
for(int i=sideCount; i>=0; i--)
(valueOfSides+i)->~t();
delete[]buffer;
throw;
}
}
die& operator=(die&& rhs) {
sideCount = rhs.sideCount;
valueOfSides = rhs.valueOfSides;
rhs.valueOfSides = nullptr;
rhs.sideCount = 0;
return *this;
}
//die& operator=(const die& rhs) not shown because its super hard.
~die() {
for(int i=sideCount; i>=0; i--)
(valueOfSides+i)->~t();
delete[]reinterpret_cast<char*>(valueOfSides);
}
};
As we've said before, getting this stuff right is crazy hard. Use a std::vector.
Use std::vector.
#include <iostream>
#include <initalizer_list>
#include <vector>
template<class T>
class die {
public:
die() = default;
die(std::initializer_list<T> list)
: sides{list}
{ /* DO NOTHING */ }
private:
std::vector<T> sides{};
};
int main() {
die<int> sixsided({1,2,3,4,5,6});
}
One way you can do this, using more of a C technique, is a variable argument list:
#include <cstdarg>
#include <iostream>
template <class t>
class die {
private:
int sideCount;
t* valueOfSides;
public:
die(int side, ...) {
sideCount = side;
valueOfSides = new t[side];
va_list args;
va_start(args, side);
for (int counter = 0; counter < side; counter++) {
valueOfSides[counter] = va_arg(args, t);
}
va_end(args);
}
~die() {
delete[] valueOfSides;
}
};
int main() {
die<int> sixsided(6, 1,2,3,4,5,6);
}
Rather than passing an array, you're passing the parameters individually (i.e. no need for a temporary array) and using a va_list to access them.
Also, the calls to malloc and free were replaced with new and delete which is the C++ way of allocating and deallocating memory.
The C++ solution:
template <class t>
class die {
private:
int sideCount;
t* valueOfSides;
public:
die(int side, t arr[]) {
sideCount = side;
valueOfSides = new T[side]
for (int counter = 0; counter < side; counter++) { //always initialize variables
valueOfSides[i] = arr[i];
}
}
~die() {
delete[] valueOfSides;
}
};
int main() {
int arr[6] = { 1,2,3,4,5,6 };
die<int> sixsided(6, arr);
}
The new operator is like malloc and the delete and delete[] operators are like free. They are dynamic allocators.
C solution:
template <class t>
class die {
private:
int sideCount;
t* valueOfSides;
public:
die(int side, t arr[]) {
sideCount = side;
valueOfSides = (t*)malloc(side * sizeof(t));
for (int counter = 0; counter < side; counter++) { //always initialize variables
valueOfSides[i] = arr[i];
}
}
~die() {
free(valueOfSides);
}
};
int main() {
int arr[6] = { 1,2,3,4,5,6 };
die<int> sixsided(6, arr);
}
Note: in C the <iostream> header will not work, this is C++ only.
There are other containers, namely std::vector, that can work, but this is the solution for your answer.
I am trying to create a map containing shared_ptr as values.In the function deleteB, I iterate through the map looking for a particular key value, when found, I erase the particular key, value pair and break out of the for loop, but as soon I come out of the deleteB function, the program crashes.I used address sanitizer and it shows heap use after free error.Not sure, where exactly this crash is happening.
struct MyObj{
int val;
void* ctx;
};
class A{
private:
MyObj obj;
int countVal;
public:
A(int value){
countVal = value;
obj = (MyObj){countVal, this};
}
~A(){}
MyObj getObj(){
return obj;
}
};
class B{
private:
int count = 0;
map<uint32_t, shared_ptr<A>> mB;
public:
void createB(MyObj &obj, int &getCount){
++count;
mB[count] = make_shared<A>(count);
obj = mB[count]->getObj();
getCount = count;
}
void deleteB(int Val){
if(!mB.empty()){
for(auto &a : mB){
if(a.first == Val){
mB.erase(a.first);
break;
}
}
}
}
};
int main(){
B b;
MyObj objVal;
int count = 0;
b.createB(objVal, count);
b.deleteB(count);
return 0;
}
I want the bag class to have an array of item objects that is dynamically allocated but not sure how to do this. Also need someone to have a look at the rest of my code. I want to add Item objects to a Bag object and perform operations on the thus formed ADT as is evident from the code.
Item.h
#ifndef ITEM_H
#define ITEM_H
class Item
{
char* item_name;
public:
Item(char *name);
void display_item(Item i);
~Item();
protected:
private:
};
#endif
Item.cpp
#include "Item.h"
#include<string.h>
#include<iostream>
#include<malloc.h>
using namespace std;
Item::Item(char* name)
{
item_name = new char[sizeof(name)];
strcpy(item_name,name);
}
void Item::display_item(Item i)
{
cout<<i.item_name<<" ";
}
Item::~Item()
{
}
Bag.h
#include "Item.h"
#ifndef BAG_H
#define BAG_H
class Bag
{
int no_of_items;
int capacity;
Item list[];
public:
Bag(int no_of_items);
void add(Item i);
void display();
~Bag();
protected:
private:
};
#endif
Bag.cpp
#include "Bag.h"
#include "Item.h"
#include<malloc.h>
Bag::Bag(int capacity)
{
Item list[capacity];
no_of_items =0;
}
void Bag::add(Item i)
{
if(no_of_items<capacity)
{
list[no_of_items] = i;
no_of_items++;
}
else
{
cout<<"bag is full";
}
}
void Bag:: display()
{
for(i=0;i<no_of_items;i++)
{
display_item(list[i]);
}
}
Bag::~Bag()
{
//dtor
}
I'll not speak on your code, if you have problems with it, ask in a separate question with minimal code to reproduce the error. Here is a link, at the end of this answer, explaining how to dynamically allocate memory for your array. If you are doing so because you need a variable sized array, I would recommend a vector. While an object of type array must have the size defined at compile time, a vector does not have this requirement, and you can use vector_pushback to add new elements with ease. But if you insist on using an array, follow the instructions here: http://www.cplusplus.com/forum/articles/416/
As possible, always use STL containers. They have analogous interface and are well documented. Most of them are dynamic. So, your code with STL containers (std::string and std::vector) could look like:
#include <string>
#include <vector>
#include <iostream>
class Item {
public:
Item(const std::string& name) : item_name(name) {}
virtual ~Item() {}
void display_item() {
std::cout << item_name << " ";
}
private:
std::string item_name;
};
class Bag {
public:
void add(const Item& i) {
items.push_back(i);
}
void display() {
for(std::vector<Item>::iterator it = items.begin();
it != items.end(); ++it)
it->display_item();
}
private:
std::vector<Item> items;
};
As your question is aiming on how to implement your example with dynamic allocation, the code above without STL containers can be done as:
#include <cstring>
#include <algorithm>
#include <iostream>
class Item {
public:
Item() : item_name(0) {} // required for new[] expression
Item(const char* name) : item_name(0) {
copyName(name);
}
virtual ~Item() {
delete[] item_name; // don't forget to free the allocated memory
}
void display_item() const {
std::cout << item_name << " ";
}
Item& operator=(const Item& other) { // required for copying
copyName(other.item_name);
return *this;
}
private:
void copyName(const char* str) {
// get the size of the new name and delete the actual name
const size_t name_size = strlen(str);
delete[] item_name;
// allocate memory for new name and copy it
item_name = new char[name_size + 1]; // extra place for '\0'
strcpy(item_name, str);
}
char* item_name;
};
class Bag {
public:
Bag(size_t cap = 0) :
items(cap ? new Item[cap] : 0), capacity(cap), size(0) {}
virtual ~Bag() {
delete[] items;
}
void add(const Item& i) {
// "resize" the actual array if there is no space for a new item
if(size == capacity) {
// allocate new array and copy the actual content
capacity += 100;
Item* temp = new Item[capacity];
std::copy(items, items + size, temp);
// delete the actual array and assign the newly allocated one
delete[] items;
items = temp;
temp = 0;
}
// add the new item
items[size] = i;
size++;
}
void display() {
for(size_t i = 0; i < size; ++i)
items[i].display_item();
}
private:
Item* items;
size_t capacity;
size_t size;
};
I'm looking for a design pattern which can store vector of pointers and can remove the vector of pointers based on the demand.
This is my existing code path.
### implementation.h
class A {
A() {}
private:
void AggregateMetrics();
void FlushMetrics();
X* x_;
Y* y_;
};
class X {
public:
void CreateFiles(vector<B*> *objects, string path);
};
class B {
B() {
m_ = 0, n_ = 0;
}
private:
int m_, n_;
};
### implementation.cpp
void A::A() {
x_ = new X();
y_ = new Y();
}
void A::AggregateMetrics() {
}
void A::FlushMetrics () {
vector<B*> objects;
x_->CreateFiles(&objects, path);
// In my new code, we are going to move the above two lines
// to AggregateMetrics() and i need to find a way to store
// the vector<B*>objects;
y_->Flush(objects);
return;
}
void X::CreateFiles(vector<B*> *objects, string path) {
CHECK(objects.empty());
for (int i = 0; i < 10; i++) {
objects->push_back(new B());
}
}
Here is my new code:
### implementation.h
class A {
A() {}
private:
void AggregateMetrics();
void FlushMetrics();
X* x_;
Y* y_;
};
class X {
public:
void CreateFiles(vector<B*> *objects, string path);
};
class B {
B() {
m_ = 0, n_ = 0;
}
private:
int m_, n_;
};
class PointerManager {
public:
PointerManager() {}
void SetPointers(vector<B*>& objects);
vector<B*> GetPointers();
private:
vector<B*>objects_;
};
### implementation.cpp
PointerManager::SetPointers(vector<B*>& objects) {
objects_ = objects;
}
vector<B*> PointerManager::GetPointers() {
return objects_;
}
void A::A() {
x = new X();
y = new Y();
mgr_ = new PointerManager();
}
void A::AggregateMetrics() {
vector<B*> objects;
x->CreateFiles(&objects, path);
mgr_->SetPointers(objects);
}
void A::FlushMetrics () {
auto objects = mgr_->GetPointers();
y->Flush(objects);
return;
}
void X::CreateFiles(vector<B*> *objects, string path) {
CHECK(objects.empty());
for (;;) {
objects->push_back(new B());
}
}
I'm basically creating a new class called PointerManager which can hold these pointers after the creation and can return when needed. What would be the ideal design here? Can you guys suggest a design pattern?
I suggest using smart pointer and store them into a container to avoid any memory leak.
Here's the version of your design using smart pointer
implementation.hpp :
#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <cassert>
class B {
public:
B() {
m_ = 0, n_ = 0;
}
private:
int m_, n_;
};
class Y{
public:
Y(){}
~Y(){}
void Flush(std::vector<std::unique_ptr<B>>& objects);
};
class X {
public:
void CreateFiles(std::vector<std::unique_ptr<B>> &objects, std::string path);
};
class PointerManager {
public:
PointerManager() {}
void InsertPointer(std::unique_ptr<B> &object);
void SetPointers(std::vector<std::unique_ptr<B>> &objects);
std::vector<std::unique_ptr<B>> &GetPointers();
private:
std::vector<std::unique_ptr<B>> objects_;
};
class A {
public:
A();
void AggregateMetrics();
void FlushMetrics();
private:
X* x_;
Y* y_;
PointerManager* mgr_;
};
implementation.cpp
#include "implementation.hpp"
void Y::Flush(std::vector<std::unique_ptr<B>>& objects){
for(int i =0;i<objects.size();i++){
objects[i].release();
}
}
void X::CreateFiles(std::vector<std::unique_ptr<B>> &objects, std::string path) {
assert(objects.empty());
for (int i = 0; i < 5;i++) {
std::cout << "for loop in CreatesFiles " << std::endl;
objects.emplace_back(new B);
}
}
void PointerManager::InsertPointer(std::unique_ptr<B> &object) {
std::cout << "InsertPointer " << std::endl;
objects_.push_back(std::move(object)); // object now belongs to PointerManager
}
void PointerManager::SetPointers(std::vector<std::unique_ptr<B>> &objects){
for(int i=0;i<objects.size();i++){
this->InsertPointer(objects[i]);
}
}
std::vector<std::unique_ptr<B>>& PointerManager::GetPointers() {
std::cout << "Get Pointers" << std::endl;
return objects_;
}
A::A() {
x_ = new X();
y_ = new Y();
mgr_ = new PointerManager();
}
void A::AggregateMetrics() {
std::cout << "Aggregate Metrics " << std::endl;
std::string path = ".";
std::vector<std::unique_ptr<B>> objects;
x_->CreateFiles(objects, path);
mgr_->SetPointers(objects);
}
void A::FlushMetrics () {
std::cout << "Flush Metrics " << std::endl;
y_->Flush(mgr_->GetPointers());
return;
}
This run fine with CLANG 3.4.2 and g++ 4.9.3 using -std=c++11 flag.
What you are basically asking is: "how do I implement my own memory management using raw pointers?"
And the answer to that is: you don't.
Modern day C++ offers concepts such as smart pointers or unique/shared pointers that take a lot of that "management" burden from the shoulders of your application code.
So the real answer here is: step back, and learn how to use C++ with all the means that are available in 2017; instead of writing code that would have been written like that 15, 20 years ago.
Searched around and couldn't find any advice to my problem. I'm trying to make a copy constructor for a class that has a private variable that includes a pointer to an Abstract Base Class.
#include "BaseClass.hh"
ClassA::ClassA()
{ }
/* Copy construct a ClassA object */
ClassA::ClassA(const ClassA& obj)
{
std::map<std::string, BaseClass*>::const_iterator it;
//ClassA copy = obj;
for(it = obj.ind.begin(); it != obj.ind.end(); it++)
{
copy.ind[it->first]=(it->second);
}
}
//in .hh file
private:
std::map<std::string, BaseClass*> ind;
Am I even close? If not, how could I fix this?
There are couple of issues here.
++it; repeated in the for loop.
ClassA copy = obj; Once you return from the copy constructor, the variable copy is destroyed. So, you are not doing any copy here.
If you wish to put the value in the map as a pointer, then you need to allocate memory for the pointer variable.
Since you have are having the value in the map as BaseClass pointer, you need to know the exact type you wish to allocate memory for. The key could help here.
I'm taking the liberty of C++11 tag here.This is just for illustration purpose. Take the idea and implement it as it fits your needs. If you observe, I did not release the memory here.Left it for you.
class BaseA
{
public:
virtual void Print() = 0;
};
class Derived1A : public BaseA
{
virtual void Print()
{
std::cout << "Derived1A\n";
}
};
class Derived2A : public BaseA
{
virtual void Print()
{
std::cout << "Derived2A\n";
}
};
std::map<std::string, std::function<BaseA*()>> factory;
class ClassA
{
public:
ClassA()
{
for (auto it = factory.begin(); it != factory.end(); ++it)
{
typedef std::pair<const std::string, BaseA*> Pair;
mapType_m.insert(Pair(it->first, it->second()));
}
}
ClassA(const ClassA& other)
{
for (auto it = other.mapType_m.begin(); it != other.mapType_m.end(); ++it)
{
typedef std::pair<const std::string, BaseA*> Pair;
mapType_m.insert(Pair(it->first, factory[it->first]()));
}
}
void Print()
{
for (auto it = mapType_m.begin(); it != mapType_m.end(); ++it)
{
std::cout << "key:" << it->first << "\tValue:";
it->second->Print() ;
std::cout << "\n";
}
}
private:
std::map<std::string, BaseA*> mapType_m;
};
int main()
{
factory["Derived1A"] = []() { return new Derived1A(); };
factory["Derived2A"] = []() { return new Derived2A(); };
ClassA c1;
ClassA c2 = c1;
c2.Print();
}